TypeScript中`extends ReadonlyArray<any>`检查的异常行为疑问
问题解答
先看给出的代码示例:
type A = ReadonlyArray<'A'> type B = ReadonlyArray<'B'> type AcceptA<T extends A> = T type Test1 = AcceptA<A> // 正常通过 type Test2 = AcceptA<B> // 报错,因为B不符合T extends A的约束 type Test3 = AcceptA<B extends ReadonlyArray<any> ? B : B> // 正常通过
Test3是否应该报错?
答案是:Test3确实可以正常通过,这是TypeScript类型系统的特性导致的,并非bug。
背后的原因
直接传参的约束检查逻辑
Test2中直接传入B时,TypeScript会立刻执行泛型约束检查:判断B extends A是否成立。由于ReadonlyArray<'B'>的元素类型'B'不能赋值给'A',所以B不是A的子类型,约束检查失败,触发报错。条件类型的特殊处理
Test3中传入的是一个条件类型表达式B extends ReadonlyArray<any> ? B : B:
- 首先这个条件判断显然成立(
B本身就是ReadonlyArray<'B'>,自然符合ReadonlyArray<any>),所以最终结果还是B。 - 关键在于,TypeScript对条件类型的结果做泛型参数时,会放松约束检查的严格性。条件类型在这里相当于给
B套了一层“类型验证”的壳,TypeScript会认为经过条件判断后的类型是符合条件分支要求的,不会再去严格验证它是否满足AcceptA的T extends A约束。简单来说,条件类型的存在让TypeScript绕过了直接的子类型检查,从而允许B作为参数传入。
内容的提问来源于stack exchange,提问作者lei li
相关产品推荐
相关产品推荐

