如何修复TypeScript 5.4中的类型错误?
TypeScript 5.4.x交集处理破坏性变更导致的类型约束问题
TypeScript 5.4.x版本引入了交集处理方式的破坏性变更,以下代码在5.3.3版本中可正常运行,但在5.4.x中会报错:
type MustBeArray<T extends any[]> = T type Hmm<T extends any[]> = T extends number[] ? MustBeArray<{ [I in keyof T]: 1 }> : never
报错信息如下:
Type '{ [I in keyof T]: 1; }' does not satisfy the constraint 'any[]'.
Types of property 'toString' are incompatible.
Type 'number' is not assignable to type '() => string'.
问题原因
在TypeScript 5.4.x中,对数组类型使用keyof T时,会包含数组原型链上的方法(比如toString、push等)。当你映射所有keyof T的键并赋值为1时,这些方法属性会被覆盖为number类型,导致最终生成的类型不再符合any[]的约束(数组的原型方法应为函数类型,而非数字)。
解决方案
修改映射逻辑,只针对数组的数字索引键进行映射,避免覆盖原型方法:
type MustBeArray<T extends any[]> = T type Hmm<T extends any[]> = T extends number[] ? MustBeArray<{ [I in Extract<keyof T, number>]: 1 }> : never
或者使用as子句过滤非数字索引:
type MustBeArray<T extends any[]> = T type Hmm<T extends any[]> = T extends number[] ? MustBeArray<{ [I in keyof T as I extends `${number}` ? I : never]: 1 }> : never
这两种方式都会只保留数组的数字索引键进行映射,生成的类型仍符合any[]的约束,从而解决报错问题。
内容的提问来源于stack exchange,提问作者Dellirium
相关产品推荐
相关产品推荐

