[英]Merging types in typescript (adding keys to an existing keyof type)
如果我有一個由鍵組成的打字稿類型:
const anObject = {value1: '1', value2: '2', value3: '3'}
type objectKeys = keyof typeof anObject
然后我希望為該類型添加鍵,同時保留當前鍵,我該怎么做?
例如,如果我想將鍵“get_value1”、“get_value2”、“get_value3”添加到“objectKeys”類型
最后,我想要一個看起來像這樣的類型:
type objectKeys = keyof anObject + 'get_value1', 'get_value2', 'get_value3'
無需手動定義以“get_”為前綴的鍵,我知道我可以輸入鍵來創建這個對象——但這對我的用例來說是不可行的。 我只是想添加一些可能存在或可能不存在的鍵到類型“objectKeys”
我也知道我可以創建一個泛型或任何允許任何鍵值的類型,但是我必須知道實際的鍵名。 允許請求對象的任何鍵對我沒有幫助,我需要現有的鍵 + 我想添加的鍵。
感謝您的幫助。
為清楚起見添加:
const anObject = {val1: '1', val2: '2'}
type objectKeys = keyof typeof anObject
Object.keys(anObject).forEach(key => {
const getAddition = `get_${key}`
anObject[getAddition] = getAddition
})
// now I don't know whats next, how do I update objectKeys to include the
// additions added in the forEach loop.
// What I really want is to not have to add the 'get' values to the object
// at all, JUST to the type. I want typechecking for the get values that
// may or may not actually exist on the object.
希望那更清楚等等。
聽起來您要求串聯字符串文字類型:也就是說,您希望能夠采用字符串文字"get_"
和另一個字符串文字,如"value1"
,並且讓 TypeScript 了解如果您將這些字符串串聯起來類型你得到一個類型為"get_value1"
的字符串。 不幸的是,這個功能在 TypeScript 2.4 中不存在(並且可能在 2.5 或 2.6 中也不存在)🙁。
所以沒有辦法做你所要求的並保持嚴格的類型安全。 當然,您可以放寬類型安全並允許訪問任何未知密鑰:
const anObject = {val1: '1', val2: '2'};
const openObject: { [k: string]: any } & typeof anObject = anObject;
// replace "any" above with whatever type the get_XXX values are
Object.keys(openObject).forEach(key => {
const getAddition = `get_${key}`
openObject[getAddition] = getAddition
})
openObject.val1 = 1; // error, val1 is known to be a string
openObject.get_val1 = 1; // no error, get_val1 is any
openObject.gut_val4 = 1; // no error, oops, sorry
但你說你不想那樣做。
在這種情況下,我的建議是放棄向對象添加任意鍵,而是讓 getter(或任何它們)掛在單個get
屬性上,如下所示:
const anObject = { val1: '1', val2: '2' }
type AnObject = typeof anObject;
type ObjectKeys = keyof AnObject;
type GetAugmentedObject = AnObject & { get: Record<ObjectKeys, any> };
// replace "any" above with whatever type the get.XXX values are
const get = {} as GetAugmentedObject['get'];
Object.keys(anObject).forEach((key: ObjectKeys) => get[key] = key);
const augmentedObject: GetAugmentedObject = { ...anObject, get }
augmentedObject.val1; // ok
augmentedObject.val2; // ok
augmentedObject.get.val1; // ok
augmentedObject.get.val2; // ok
augmentedObject.get.val3; // error, no val3
augmentedObject.git.val1; // error, no git
這對開發人員來說並沒有太大的不同( obj.get.val1
與obj.get_val1
),但對 TypeScript 的跟進能力有很大的不同。 如果您對添加鍵的代碼有任何控制權,我強烈建議您像這樣做一些 TypeScript 友好的事情,因為如果您不需要的話,您不想花時間與 TypeScript 作斗爭。
否則,如果只有類型級別的字符串連接對你有用,並且你覺得你的用例足夠引人注目,也許你應該去相關的 GitHub 問題並給它一個 👍 並描述為什么它對你來說是必不可少的。
希望有幫助。 祝你好運!
您可以使用模板文字。
這是一個示例,其中屬性id
必須是#
+ key
:
interface MyInterface<K extends string> {
something: {
[key in K]: { id: `#${key}` }
}
}
所以以下是正確的:
let x: MyInterface<'foo'> = {
something: {
foo: { id: '#foo' }
}
}
但這是不正確的:
let y: MyInterface<'foo'> = {
something: {
foo: { id: 'foo' }
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.