TypeScript中'ScopeType<T, unknown>'无法分配给'ParentScopeType<S>'的问题
TypeScript条件类型赋值错误解决方案
问题核心
在test函数中执行let source: ParentScopeType<S> | undefined = scope时,出现编译错误:Type 'ScopeType<T, unknown>' is not assignable to type 'ParentScopeType<S>'。尽管ParentScopeType的两个条件分支最终都返回与S相关的类型,但条件类型的特性导致TypeScript无法正确推断类型兼容性,直接将ParentScopeType定义为S则无此问题。
解决方案
方法1:消除条件类型的分布性
TypeScript默认的条件类型是分布性条件类型,会对联合类型成员逐个解析,导致类型推断偏差。可以用元组包裹条件类型的输入,消除分布性:
type ScopeType<T, P = undefined> = { type: T; parent: P; }; // 修改ParentScopeType的定义,用元组包裹[S]消除分布性 type ParentScopeType<S extends ScopeType<any, any>> = [S] extends [ScopeType<infer T, infer P>] ? P extends ScopeType<any, any> ? S | ParentScopeType<P> : S : never; function test<S extends ScopeType<any, any>>(scope: S) { let source: ParentScopeType<S> | undefined = scope; // 编译正常 }
方法2:类型断言(应急方案)
若无法修改ParentScopeType的定义,可在赋值时使用类型断言绕过编译检查:
function test<S extends ScopeType<any, any>>(scope: S) { let source: ParentScopeType<S> | undefined = scope as ParentScopeType<S>; }
原因说明
分布性条件类型会延迟解析,直到传入具体类型才会计算结果。编译时TypeScript无法提前确认ScopeType<T, unknown>与ParentScopeType<S>的兼容性,而直接定义为S时,类型是明确的,不存在延迟解析的问题,因此可以通过编译。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

