为判别联合类型函数指定返回类型时遇TS错误求助
TypeScript联合类型索引访问报错的解决方法
报错原因
当你尝试用EitherOr['key'] | EitherOr['name']作为返回类型时,TypeScript会抛出Property 'key' does not exist on type 'EitherOr'错误,核心原因是联合类型的索引访问要求所有成员都具备该属性:
EitherOr是TOne | TSecond的联合类型,TSecond没有key属性,所以EitherOr['key']不合法;- 同理,
TOne没有name属性,EitherOr['name']也不合法。
直接解决方案
正确的返回类型应该直接取两个成员类型的对应属性做联合,也就是TOne['key'] | TSecond['name']。修正后的代码如下:
enum Keys { SOME_NAME = "some.name", SOME_ID = "some.id", } type TOne = { key: Keys }; type TSecond = { name: string }; type EitherOr = TOne | TSecond; const isOne = (obj: EitherOr): obj is TOne => 'key' in obj const getKeyOrName = (obj: EitherOr): TOne['key'] | TSecond['name'] => { return isOne(obj) ? obj.key : obj.name; }
进阶方案:用工具类型自动提取属性
如果联合类型的成员较多,不想手动逐个编写索引,可以自定义工具类型,自动提取联合类型中每个成员的指定属性:
enum Keys { SOME_NAME = "some.name", SOME_ID = "some.id", } type TOne = { key: Keys }; type TSecond = { name: string }; type EitherOr = TOne | TSecond; const isOne = (obj: EitherOr): obj is TOne => 'key' in obj // 自定义工具类型:遍历联合类型成员,提取存在的目标属性 type PickUnionProp<T, K extends keyof any> = T extends infer U ? U extends { [P in K]: any } ? U[K] : never : never; const getKeyOrName = (obj: EitherOr): PickUnionProp<EitherOr, 'key' | 'name'> => { return isOne(obj) ? obj.key : obj.name; }
这个工具类型会逐个检查联合类型的成员,仅提取成员中存在的目标属性类型,避免重复编写成员类型索引。
内容的提问来源于stack exchange,提问作者:匿名用户
相关产品推荐
相关产品推荐

