TypeScript类型报错疑问:[...Array,1]['length']无法赋值是否为TS Bug?
TypeScript类型编程报错疑问:这是Bug吗?
我编写了一个实现字符串压缩的类型Encode,预期将重复字符替换为“重复次数+字符”(单次重复则只保留字符),但在终止分支中遇到了报错:
export type Encode< S extends string, Rtn extends string = '', Last extends string = '', Array extends 1[] = [], isFirst extends boolean = true > = S extends `${infer F}${infer R}` ? isFirst extends true ? Encode<R, Rtn, F, [...Array, 1], false> : F extends Last ? Encode<R, Rtn, F, [...Array, 1], false> : Encode< R, Array['length'] extends 1 ? `${Rtn}${Last}` : `${Rtn}${Array['length']}${Last}`, F, [1], false > : S extends Last ? `${Rtn}${[...Array, 1]['length']}${Last}` // 报错:Type '[...Array, 1]["length"]' is not assignable to type 'string | number | bigint | boolean | null | undefined' // 但 [...Array, 1]['length'] 应为number类型 : `${Rtn}${Last}` type a1 = Encode<'AAABCCXXXXXXYYY'> // 预期结果:'3AB2C6X3Y'
这不是TypeScript的Bug,而是类型系统的推断限制
当Array作为泛型参数(约束为1[])时,在递归的终止分支中,TypeScript无法将[...Array, 1]['length']窄化为具体的数字字面量类型,只能识别为宽泛的number类型。而模板字符串类型对参与拼接的类型有严格约束:它需要明确的字面量类型(如3、"a")或能被编译器确认的窄化类型,宽泛的number类型无法满足这个约束,因此触发报错。
解决方案:明确类型约束
通过& number来显式约束类型,帮助TypeScript确认该值属于合法的拼接类型:
export type Encode< S extends string, Rtn extends string = '', Last extends string = '', Array extends 1[] = [], isFirst extends boolean = true > = S extends `${infer F}${infer R}` ? isFirst extends true ? Encode<R, Rtn, F, [...Array, 1], false> : F extends Last ? Encode<R, Rtn, F, [...Array, 1], false> : Encode< R, Array['length'] extends 1 ? `${Rtn}${Last}` : `${Rtn}${Array['length']}${Last}`, F, [1], false > : S extends Last ? `${Rtn}${[...Array, 1]['length'] & number}${Last}` : `${Rtn}${Last}` type a1 = Encode<'AAABCCXXXXXXYYY'> // 正确得到:'3AB2C6X3Y'
你也可以使用类型断言([...Array, 1]['length'] as number)来达到同样的效果,本质都是让编译器确认该类型符合模板字符串拼接的要求。
内容的提问来源于stack exchange,提问作者yukinotech
相关产品推荐
相关产品推荐

