TypeScript使用keyof替代字面量时出现type pattern not matched问题
问题原因
这个差异完全是TypeScript的语法规则导致的,不属于bug,是你写的类型语法不符合预期:
- 核心误区:你在类型a的条件判断里写的
{ K },并不是你以为的「属性名为K的对象类型」。在TypeScript的对象类型定义中,直接写标识符作为字段名属于「属性简写语法」,等价于{ K: K }:也就是对象有一个字面量名为K的属性,属性值的类型是泛型参数K的类型(也就是字符串字面量"foo")。 - 类型a的推导逻辑拆解:
- 首先
keyof { "foo" }的结果是"foo",所以映射类型的遍历参数K的类型固定为"foo" - 条件判断实际变成
{ foo: "bar" } extends { K: "foo" } ? true : false,前者根本不存在名为K的属性,自然返回false
- 首先
- 类型b的推导逻辑:你写的
{ "foo" }等价于{ "foo": "foo" }(部分低版本TS在省略类型的场景下会处理为{ foo: any }),{ foo: "bar" }存在符合要求的foo属性,满足extends约束,所以返回true。
修正方案
如果你想要类型a和b的逻辑一致,需要用计算属性语法来定义动态属性名,把类型a的条件判断改成:
{ foo: "bar" } extends { [Key in K]: unknown } ? true : false
修改后类型a的结果就会和b一致为true。
内容的提问来源于stack exchange,提问作者true_mogician
相关产品推荐
相关产品推荐

