如何限制TypeScript接口字段类型,使其仅依赖其他字段?
解决方案
你当前的写法无法实现需求,因为string[]是宽泛的字符串数组类型,TypeScript无法从中提取具体的字面量成员。要让pick只能取值为name数组中的具体元素,需要通过泛型来捕获数组的字面量类型:
泛型接口实现
interface T<Names extends string[]> { name: Names; pick: Names[number]; }
使用时可以手动指定泛型参数,让TypeScript明确约束name和pick的类型:
// 合法示例 const validObj: T<['a', 'b']> = { name: ['a', 'b'], pick: 'a' }; // 非法示例,TypeScript会报错 const invalidObj: T<['a', 'b']> = { name: ['a', 'b'], pick: 'c' // 类型'"c"'不能赋值给类型'"a" | "b"' };
自动推断简化写法
如果不想每次手动指定泛型参数,可以写一个辅助函数让TypeScript自动推断数组的字面量类型:
function createT<Names extends string[]>(params: T<Names>) { return params; } // 自动推断name为['a','b'],pick只能是'a'或'b' const obj = createT({ name: ['a', 'b'], pick: 'b' }); obj.pick = 'c'; // 报错:类型'"c"'不能赋值给类型'"a" | "b"'
原理说明
泛型参数Names会被约束为具体的字符串字面量数组类型(比如['a','b']),Names[number]会解析为该数组所有元素的联合类型(即'a' | 'b'),从而实现pick只能取name数组中存在的值的约束。
内容的提问来源于stack exchange,提问作者mod7ex
相关产品推荐
相关产品推荐

