如何实现str in obj时将str收窄为keyof obj类型?
实现字符串链式调用的keyof类型收窄
你已经有了能实现类型收窄的isKeyOf函数,但想要把它改成字符串的链式调用方法时,遇到了TypeScript不允许在类型守卫函数中直接用this作为返回类型的问题。下面是正确的实现方式:
步骤1:全局扩展String接口
首先在全局作用域扩展String接口,声明链式方法的类型:
declare global { interface String { isKeyOf<T extends object>(obj: T): this is keyof T; } }
这里直接指定方法返回类型为this is keyof T,表示当方法返回true时,调用该方法的字符串实例会被收窄为obj的键类型。
步骤2:实现链式方法
接下来在String.prototype上实现这个方法,注意要把字符串实例转为原始值进行判断:
String.prototype.isKeyOf = function <T extends object>(obj: T): this is keyof T { // 将String实例转为原始字符串值,再判断是否属于obj的键 return this.valueOf() in obj; };
使用示例
现在就可以像你期望的那样链式调用,TypeScript会正确收窄类型:
let key: string; // 假设这里key被赋值为某个字符串 key = "age"; const user = { name: "张三", age: 25 }; if (key.isKeyOf(user)) { // 此时key的类型已被收窄为"name" | "age" user[key] = 26; // 类型检查通过,不会报错 }
注意事项
- 如果你的代码在模块中(包含
import/export),必须把declare global包裹的接口扩展放在模块内部,否则会被视为全局脚本。 - 无需自定义
CustomString类,直接扩展原生String接口即可让所有字符串实例支持链式调用。
内容的提问来源于stack exchange,提问作者Ryuujo
相关产品推荐
相关产品推荐

