TypeScript:根据传入参数收窄函数返回类型
实现TypeScript函数的参数关联返回类型
先看原代码:
const REPORT_FILTERS = { car: 'car', bicycle: 'bicycle', boat: 'boat', } as const; type ReportFilters = keyof typeof REPORT_FILTERS; // filter 来自URL查询参数,默认是字符串类型 const { report: filter } = Object.fromEntries([ ['report', 'car'], ]) as { report: ReportFilters; }; const whichReport = (report: ReportFilters) => { const x = REPORT_FILTERS[report]; return x; }; const a = whichReport(filter);
需求:让whichReport函数根据传入的具体report参数值,返回对应的字面量类型。比如传入"car"时,返回类型是"car",而非"car" | "bicycle" | "boat"。
解决方案:使用泛型约束
修改whichReport函数,添加泛型参数让TypeScript捕获传入参数的具体字面量类型,替代宽泛的联合类型:
const whichReport = <T extends ReportFilters>(report: T): typeof REPORT_FILTERS[T] => { return REPORT_FILTERS[report]; };
修改后效果:
- 传入
"car"时,泛型T会被推断为"car",返回类型就是typeof REPORT_FILTERS["car"],即字面量类型"car" - 传入
"bicycle"时,返回类型自动对应"bicycle",以此类推
如果需要让从URL获取的filter也能被推断出具体类型,可以优化类型断言或添加类型守卫:
// 精准类型断言,直接指定filter为"car"字面量类型 const { report: filter } = Object.fromEntries([ ['report', 'car'], ]) as { report: "car"; }; // 或者用类型守卫缩小实际场景中URL参数的类型 function isReportFilter(value: string): value is ReportFilters { return Object.keys(REPORT_FILTERS).includes(value); } // 实际业务中处理URL参数的示例 const rawFilter = "car"; if (isReportFilter(rawFilter)) { const a = whichReport(rawFilter); // a的类型为"car" }
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

