likes
comments
collection
share

如何在 TypeScript 中根据不同的参数类型,返回不同类型的结果

作者站长头像
站长
· 阅读数 45

条件返回类型是 TypeScript 的一个强大功能,它可以根据我们传入参数的类型为函数返回不同类型。当你想要保证我们的类型安全并确保函数返回类型与我们预期类型匹配时,就可以用它。

例如,我们要编写一个接收两个参数的加法的函数。而且我们希望这个函数的返回值根据传入参数类型的不同来返回不同类型的返回值。如果参数是字符串,则将两个字符串连接起来并返回。如果参数是数字,它将两个数字相加并返回总和。

代码示例:

function plus<T extends string | number>(a: T, b: T): T extends string ? string : number {
  if (typeof a === 'string' && typeof b === 'string') {
    return (a + b) as string;
  }

  if (typeof a === 'number' && typeof b === 'number') {
    return (a + b) as number;
  }

  throw new Error('两个参数必须是相同的类型');
}

const result1 = plus(1, 2); // 返回的结果是number类型
const result2 = plus('Hello ', 'World'); // 返回的结果是String类型

在上面的示例代码中,plus函数接受了两种类型的参数(string和number),我们用泛型T继承string类型和number类型然后赋给我们的参数。然后在函数里面使用if条件判断,判断接收的参数类型来指定返回的类型,如果传入的参数类型是String就返回String类型的返回值,如果传入的参数类型是number就返回number类型的返回值。

但是,TypeScript 无法正确推断函数实现中的返回类型。编译器在第 3 行和第 7 行报告错误,尽管在调用函数时在第 14 行和第 15 行正确推断了返回类型。

如何在 TypeScript 中根据不同的参数类型,返回不同类型的结果

如何在 TypeScript 中根据不同的参数类型,返回不同类型的结果

出现这个问题在于泛型T,函数的参数和返回值的类型都使用了泛型T,这样导致了循环引用错误。我们可以使用R来替换我们的返回泛型,我们可以为返回类型使用一个单独的类型参数。

代码示例:

function plus<T extends string | number, R = T extends string ? string : number>(a: T, b: T): R {
  if (typeof a === 'string' && typeof b === 'string') {
    return (a + b) as R;
  }

  if (typeof a === 'number' && typeof b === 'number') {
    return (a + b) as R;
  }

  throw new Error('Both arguments must be of the same type');
}

const result1 = plus(1, 2); // 返回的结果是number类型
const result2 = plus('Hello ', 'World'); // 返回的结果是String类型

在上面的代码中,R类型参数用于根据条件类型指定返回类型。这样可以避免循环引用的错误并且可以允许正确返回结果。

写在最后

伙伴们,如果你觉得我写的文章对你有帮助就给zayyo点一个赞👍或者关注➕都是对我最大的支持。当然你也可以加我微信:IsZhangjianhao,邀你进我的前端学习交流群,一起学习前端,成为更优秀的工程师~