如何实现带动态命名属性的TypeScript自定义类型?
TypeScript动态布尔属性类型实现方案
你的代码有两个关键问题需要修正,同时要结合TypeScript的泛型和类型约束来实现需求:
1. 修正泛型类型定义
首先,TypeScript的泛型需要正确的语法和类型约束,我们可以用交叉类型将固定属性和动态属性结合起来,确保动态属性是布尔类型:
// 泛型FlagName约束为string类型,确保是合法的属性名 type ItemWithNamespaceFlag<FlagName extends string> = { name: string; color: "red" | "blue"; } & Record<FlagName, boolean>;
这里用Record<FlagName, boolean>来定义动态属性的类型,再和固定属性的对象类型交叉,就能得到同时包含固定属性和指定动态布尔属性的类型。
2. 处理编译时/运行时属性名的差异
TypeScript是编译时类型系统,泛型参数需要是编译时可确定的类型:
如果属性名是编译时已知的字面量,可以用
as const断言让TypeScript推断出具体的字面量类型:// 用as const把变量类型锁定为"isActive"字面量 const myLiteralProp = "isActive" as const; const item1: ItemWithNamespaceFlag<typeof myLiteralProp> = { name: "foo", color: "red", [myLiteralProp]: true }; // 此时item1的类型明确包含isActive: boolean,TypeScript会做严格校验如果属性名是运行时动态获取的字符串,由于编译时无法确定具体值,只能将泛型参数设为
string,此时类型会允许任意字符串作为布尔属性名:function getStringFromSomewhere(): string { return "isEnabled"; } let myRuntimeProp: string = getStringFromSomewhere(); const item2: ItemWithNamespaceFlag<string> = { name: "bar", color: "blue", [myRuntimeProp]: false }; // 此时item2的类型允许任意字符串属性对应布尔值
原代码的问题说明
- 泛型定义语法错误:正确的泛型类型定义需要用
=连接类型体,且泛型参数最好添加类型约束(extends string) - 运行时变量无法作为泛型参数:泛型参数必须是编译时可确定的类型,动态字符串只能对应
string泛型参数
内容的提问来源于stack exchange,提问作者acenturyandabit
相关产品推荐
相关产品推荐

