如何在TypeScript中以对象字符串字面量属性为同对象键类型(非映射类型)
实现方法
不用映射类型也能实现这个约束,核心思路是靠泛型推导字面量类型,把bar的具体值和baz的参数结构绑定起来,有两种可行方式:
方式一:用辅助函数自动推导(推荐)
写一个泛型函数来创建对象,TypeScript会自动识别bar的字面量类型,然后强制baz的参数只能包含这个键:
// 泛型辅助函数,J会自动推导为bar的字面量类型 function createFoo<J extends string>(foo: { bar: J; // 用索引签名约束参数结构,仅允许J对应的键存在 baz: (param: { [key in J]: any }) => void; }) { return foo; } // 创建对象时,TypeScript自动约束baz的参数 const test = createFoo({ bar: 'id', baz: ({ id }) => console.log(id) // 这里只能用id,写其他属性直接报错 }); // 错误示例:baz里用了name,TypeScript会提示类型不匹配 const wrongTest = createFoo({ bar: 'id', baz: ({ name }) => console.log(name) // 报错:类型"{ name: any; }"无法赋值给"{ id: any; }" });
方式二:手动指定泛型参数
如果不想用辅助函数,也可以直接给接口指定泛型参数,把bar的字面量类型显式传进去:
interface Foo<J extends string> { bar: J; baz: (param: { [key in J]: any }) => void; } // 手动指定泛型为'id',约束baz的参数只能有id键 const test: Foo<'id'> = { bar: 'id', baz: ({ id }) => console.log(id) };
注:这里的
{ [key in J]: any }只是结合泛型的索引签名写法,不属于你提到的复杂映射类型,完全符合要求。
内容的提问来源于stack exchange,提问作者Senyaak
相关产品推荐
相关产品推荐

