如果我在TypeScript中创建此常量:
const PARAMS = {
green: {color: 0x007700},
black: {color: 0x000000},
white: {color: 0xffffff},
};
它推导类型为{ 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},
});
更新
您可以使它成为完全通用的,如@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>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句