如何定义返回值类型与参数类型一致的函数?
如何定义返回值类型与参数类型一致的函数?
你现在写的这个indented函数,参数是string | string[],返回值也是这个联合类型,但肯定会遇到一个闹心的问题——明明传入的是单个字符串,TypeScript却提示返回值可能是数组,这种模糊的类型提示太不精准了对吧?
其实咱们用TypeScript的泛型就能完美解决这个问题,让函数返回值的类型和输入参数的类型严格对应:传字符串就返回字符串,传字符串数组就返回数组。
先给你改造好的代码,咱们一步步说:
// 先补全你用到的toArray工具函数(如果你的实现不一样,调整逻辑就行) const toArray = <T extends string | string[]>(input: T): string[] => { return Array.isArray(input) ? input : [input]; }; export const indented = <T extends string | string[]>( input: T, level: number = 1 ): T => { if (level === 0) return input; const toAdd = "\t".repeat(level); const lines: string[] = toArray(input); // 补全你没写完的map逻辑:非空行添加缩进 const newLines = lines.map((line) => { return line === "" ? "" : `${toAdd}${line}`; }); // 根据输入类型返回对应结果,确保类型匹配 return Array.isArray(input) ? newLines as T : newLines[0] as T; };
核心改动是这几点:
- 给函数加上泛型
<T extends string | string[]>,让TypeScript自动捕获你传入的具体类型(是单个字符串还是数组) - 把返回值类型直接设为
T,这样TS就明确知道返回值和输入类型完全一致 - 最后返回的时候,判断输入是否为数组,对应返回数组或单个字符串,用
as T做类型断言(因为我们明确知道这里的类型和输入的T匹配)
举个例子哈:
- 调用
indented("hello world", 2),TS会直接推断返回值是string,不会再提示可能是数组 - 调用
indented(["第一行", "第二行"], 1),返回值会被推断为string[],完全符合预期
这样改造后,函数的类型提示就精准多了,再也不用在调用后额外做类型判断啦~
备注:内容来源于stack exchange,提问作者John Deighan
相关产品推荐
相关产品推荐

