TypeScript联合类型类型谓词TS2677错误解决求助
解决TypeScript联合类型类型谓词的TS2677错误
我有多个由服务器生成的TypeScript联合类型,示例代码功能正常,但在WebStorm等编辑器中,类型谓词处触发TS2677错误:TS2677: A type predicate's type must be assignable to its parameter's type.。使用TypeScript 5.2.2,希望不借助@ts-ignore消除该错误。
原代码示例:
type KeysOfUnion<T> = T extends T ? keyof T : never; export type ExtractValueTypeFromUnion<T, K extends KeysOfUnion<T>> = K extends string ? (T extends { [key in `${K}`]: infer ResultType } ? ResultType : never) : never function isUnionVariant<U extends Record<string, any>, K extends KeysOfUnion<U>>( union: U, key: K ): union is K extends string ? { [key in `${K}`]: ExtractValueTypeFromUnion<U, K> } : never { return key in union; } type A = { "a": { a1: string } } | { "b": { b1: string } } const doSomething = (a: A) => { if (isUnionVariant(a, "a")) { a.a.a1 } else { a.b.b1 } }
解决方案
问题根源在于原类型谓词构造的新对象类型,未被TypeScript识别为联合类型U的子类型。我们可以通过直接从联合类型中筛选目标成员来修正:
type KeysOfUnion<T> = T extends T ? keyof T : never; // 提取联合类型中包含指定key的成员类型 type UnionMemberWithKey<U, K extends KeysOfUnion<U>> = U extends Record<K, infer _V> ? U : never; function isUnionVariant<U extends Record<string, any>, K extends KeysOfUnion<U>>( union: U, key: K ): union is UnionMemberWithKey<U, K> { return key in union; } type A = { "a": { a1: string } } | { "b": { b1: string } } const doSomething = (a: A) => { if (isUnionVariant(a, "a")) { a.a.a1 // 类型推断正常 } else { a.b.b1 // 类型推断正常 } }
说明
通过UnionMemberWithKey类型工具,直接从联合类型U中筛选出包含指定key K的成员,确保类型谓词返回的类型明确是U的子类型,从而消除TS2677错误,同时保留原有的类型推断能力。
内容的提问来源于stack exchange,提问作者AlexeyChirkov
相关产品推荐
相关产品推荐

