![](/img/trans.png)
[英]Can you enforce a key on an object but let typescript deduce the type of Value?
[英]Can I specify a value type in TypeScript but still let TS deduce the key type?
如果我在TypeScript中創建此常量:
const PARAMS = {
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
};
它推導類型為{ green: {color: number}; black: { color: number }; white: { color: number }; }
{ green: {color: number}; black: { color: number }; white: { color: number }; }
{ green: {color: number}; black: { color: number }; white: { color: number }; }
。
但是我從上下文知道值的類型應該是THREE.MeshBasicMaterialParameters
。 我可以使用索引類型來聲明:
const PARAMS: {[name: string]: THREE.MeshBasicMaterialParameters} = {
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
};
但隨后我失去了按鍵的特定可能性(“綠色”,“黑色”或“白色”)。 我可以通過寫出所需的完整類型來更精確地建模:
const PARAMS: {
green: THREE.MeshBasicMaterialParameters,
black: THREE.MeshBasicMaterialParameters,
white: THREE.MeshBasicMaterialParameters
} = {
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
};
但這是非常冗長和重復的。
有沒有一種方法可以更簡潔地獲取我想要的類型?
您可以通過使用通用映射類型來減少詳細程度
type ParamsType<Colors extends string> = {
[c in Colors]: THREE.MeshBasicMaterialParameters;
}
const PARAMS: ParamsType<'green' | 'black' | 'white'> = {
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
};
但是您仍然必須重復兩次顏色名稱。 如果希望打字稿推斷出鍵,則必須引入中間函數,在運行時完全沒有用。 我不知道有什么其他方法可以使Typescript來推斷通用參數-github上有一項提議允許扣除默認模板參數,但到目前為止沒有實現。
function inferColorKeys<Colors extends string>(params: ParamsType<Colors>): ParamsType<Colors> {
return params;
}
const PARAMS = inferColorKeys({
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
});
UPDATE
您可以按照@jcalz的建議,使其完全通用,方法是將inferKeys
變成一個帶有顯式通用參數並返回一個推斷其通用參數的函數。 它必須是兩個函數,因為一個函數不能具有某些顯式的通用參數和某些推斷的參數。 而且,它使用了內置的Record
類型,該類型定義為type Record<K extends string, V> = {[k in K]: V}
。
const inferKeys = <V>() => <K extends string>(x: Record<K,V>): Record<K,V> => x;
const PARAMS = inferKeys<THREE.MeshBasicMaterialParameters>()({
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
});
PARAMS
類型推斷為
Record<"green" | "black" | "white", THREE.MeshBasicMaterialParameters>
這是您的選擇嗎?
const PARAMS = {
green: {color: 0x007700} as THREE.MeshBasicMaterialParameters,
black: {color: 0x000000} as THREE.MeshBasicMaterialParameters,
white: {color: 0xffffff} as THREE.MeshBasicMaterialParameters,
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.