如何在TypeScript函数中实现仅接受传入对象键的类型约束?
如何让TypeScript函数返回的内部函数仅接受传入对象的合法键?
在TypeScript中,当给对象标注Record<string, string>类型后,keyof typeof 对象会被抹平成string,导致无法通过类型约束限制键的合法性。比如下面的代码中,内部函数acceptOnlyKeysFromDictionaty会接受任意字符串,无法拦截非法键:
const myFunction = function(dictionary : Record<string,string> ) { return function acceptOnlyKeysFromDictionaty(key : keyof typeof dictionary){ console.log("key", key); } }; // 不会被TypeScript拦截,但属于非法调用 myFunction({"allowedKey" : "value"})("illegalKey")
解决方案:使用泛型保留原始对象的键类型
通过为外部函数添加泛型约束,可以捕获传入对象的具体键的联合类型,避免被Record<string, string>抹平。修改后的代码如下:
const myFunction = function<T extends Record<string, string>>(dictionary: T) { return function acceptOnlyKeysFromDictionary(key: keyof T) { console.log("key", key); }; };
效果验证
此时调用内部函数时,TypeScript会严格校验键的合法性:
// 合法调用:正常通过类型检查 const validateKey = myFunction({ "allowedKey": "value", "anotherValidKey": "test" }); validateKey("allowedKey"); validateKey("anotherValidKey"); // 非法调用:TypeScript直接报错 validateKey("illegalKey"); // 类型“"illegalKey"”的参数不能赋给类型“"allowedKey" | "anotherValidKey"”的参数。
原理说明
泛型T extends Record<string, string>会自动推导传入dictionary的具体类型,保留其所有键的字面量联合类型。内部函数的key参数被约束为keyof T,也就是原始对象的所有合法键的集合,从而实现了严格的类型校验。
内容的提问来源于stack exchange,提问作者chilly_maximus
相关产品推荐
相关产品推荐

