TypeScript键重映射中复杂类型推断报错:Foo<P>无法赋值问题
问题解析与解决
首先看你的Foo类型定义:
type Foo<T extends string> = [T] extends [infer Y] ? Y : never
这个类型本质上是一个恒等类型——因为[T]必然能匹配[infer Y],所以Y就是T本身。但问题出在泛型参数在映射类型的as子句中,TypeScript对条件类型的推断行为。
报错原因
在Test类型中,P是T[number],而T是一个泛型(约束为Array<string>)。此时P是一个未具体化的泛型类型参数,当你把它传入Foo时,TypeScript在解析条件类型[P] extends [infer Y]时,无法确定Y的具体类型边界——虽然P被约束为string,但条件类型的推断会被延迟,导致TypeScript暂时将Y推断为unknown,而unknown不能作为对象的键(对象键要求是string | number | symbol),因此报错。
而Test_2和Test_3能正常编译,是因为传入Foo的是具体类型("foo"或string),TypeScript可以直接确定Foo的返回类型是合法的键类型。
解决方法
有两种简单的修正方式:
1. 简化Foo类型(推荐)
既然Foo本质是恒等类型,直接返回T即可:
type Foo<T extends string> = T type Test<T extends Array<string>> = { [P in T[number] as Foo<P>]: undefined }
2. 给推断的Y加上约束
在条件类型的推断中明确Y的约束,让TypeScript知道它必然是string:
type Foo<T extends string> = [T] extends [infer Y extends string] ? Y : never type Test<T extends Array<string>> = { [P in T[number] as Foo<P>]: undefined }
两种方式都能让TypeScript正确识别Foo<P>是合法的对象键类型,从而消除报错。
内容的提问来源于stack exchange,提问作者zRain
相关产品推荐
相关产品推荐

