TypeScript RxJS:将联合类型数组映射为单一类型的问题
解决RxJS中联合类型数组映射后的类型冗余问题
我懂你碰到的这个小麻烦——TypeScript在这里的类型推断有点死板,明明两个分支返回的是完全一样的类型,却硬把它们合并成了重复的联合类型{field:string, direction: boolean} | {field:string, direction: boolean}。其实解决起来很简单,给你几个实用的方案:
方案1:给map显式指定返回类型
最直接的办法就是告诉map操作符我们最终要的是什么类型,跳过TypeScript那套“自作聪明”的推断:
import { from } from 'rxjs/observable/from'; var sortFields: Array<string | { field: string, direction: boolean }>; from(sortFields) // 这里通过泛型明确指定map的返回类型 .map<{ field: string, direction: boolean }>(sortField => { if (typeof sortField === "string") return { field: sortField, direction: true }; else return sortField; // 优化点:直接返回原对象,不用重复解构赋值 });
方案2:提前定义类型别名(更推荐)
如果这个排序字段类型会在代码里多次用到,不如先给它起个名字,代码可读性也更高:
import { from } from 'rxjs/observable/from'; // 先定义统一的类型别名 type SortField = { field: string, direction: boolean }; var sortFields: Array<string | SortField>; from(sortFields) .map<SortField>(sortField => { return typeof sortField === "string" ? { field: sortField, direction: true } : sortField; });
这样不仅解决了类型推断的问题,以后要修改这个类型结构也只需要改一处,维护起来更方便。
方案3:用类型断言快速修复
如果只是临时场景不想改太多代码,也可以在返回值上用类型断言“说服”TypeScript:
import { from } from 'rxjs/observable/from'; var sortFields: Array<string | { field: string, direction: boolean }>; from(sortFields) .map(sortField => { if (typeof sortField === "string") return { field: sortField, direction: true } as { field: string, direction: boolean }; else return sortField; });
不过这个方案更适合临时救急,长期来看还是前两种方案更优雅。
为什么会出现这个问题呢?其实是TypeScript的类型推断逻辑导致的:它会分别分析map回调里每个分支的返回类型,然后把它们合并成联合类型,但没意识到这两个分支的结果其实是完全相同的类型。只要我们显式指定最终类型,就能纠正这个推断偏差啦。
内容的提问来源于stack exchange,提问作者Jordi
相关产品推荐
相关产品推荐

