TypeScript自定义UnpackArrayType对never、any类型推导结果异常问题
问题本质
这是never和any作为TypeScript特殊类型,在条件类型推断中的固有特性导致的:
never类型的处理逻辑
never是TypeScript的底类型,是所有类型的子类型,因此[never] extends [(infer R)[]]的判断结果为真,会进入infer R的分支。但never本身没有任何类型信息可以用来推导R的具体类型,此时TypeScript会将R回退为默认的unknown类型,所以最终返回unknown。
any类型的处理逻辑
any是TypeScript的特殊兼容类型,它可以匹配任何类型的约束,因此[any] extends [(infer R)[]]的判断同样为真。和never的情况一致,any无法提供足够的信息推导R的类型,所以R也会被推断为unknown。
修复方案
可以在数组判断前优先对never和any做特殊判断,就能得到符合预期的结果:
type UnpackArrayType<T> = // 优先处理never类型 [T] extends [never] ? false // 判断是否为any:只有any类型满足0 extends 1 & T的规则 : 0 extends (1 & T) ? false // 正常数组解包逻辑 : [T] extends [(infer R)[]] ? R : false; type UA<T> = UnpackArrayType<T>; // 测试结果符合预期 type TypeTesting = { "never": UA<never>, // false "never[]": UA<never[]>, // never "any": UA<any>, // false "any[]": UA<any[]>, // any "unknown": UA<unknown>, // false "unknown[]": UA<unknown[]>, // unknown "null": UA<null>, // false "null[]": UA<null[]>, // null "undefined": UA<undefined>, // false "undefined[]": UA<undefined[]>, // undefined "number": UA<number>, // false "number[]": UA<number[]>, // number }
内容的提问来源于stack exchange,提问作者mont
相关产品推荐
相关产品推荐

