【问题标题】:TypeScript: How to make a conditional type that returns an array based on the condition?TypeScript:如何制作一个根据条件返回数组的条件类型?
【发布时间】:2021-07-26 19:45:44
【问题描述】:

如果输入参数是数组类型,我正在尝试键入一个应该返回数组类型的函数,否则返回一个普通参数。这是我的尝试:

function test<T extends number|number[]>(a: T):T extends number[] ? string[] : string {
  if (Array.isArray(a)) {
    return ['123', '45']
  }
  return '123'
}

我在返回语句中收到错误:Type 'string' is not assignable to type 'T extends number[] ? string[] : string'.

我正在寻找的是以下内容:

const a = test(3) // "a" is string type
const b = test([1,2,3]) // "b" is string[] type

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    只需使用overload你的函数:

    function test(a: number): '123'
    function test(a: number[]): string[]
    function test<T extends number | number[]>(a: T) {
        if (Array.isArray(a)) {
            return ['123', '45']
        }
        return '123'
    }
    test(2) // '123'
    test([23]) // string[]
    

    条件类型中不需要。

    Playground

    【讨论】:

      【解决方案2】:

      基于this,Typescript 不会根据函数中的类型保护推断不同的返回类型。但是您可以像这样定义多个函数签名:

      function test(a: number): string;
      function test(a: number[]): string[];
      
      function test<T extends number|number[]>(a: T): string | string[]{ 
        if (Array.isArray(a)) {
          return ['123', '45'] 
        }
        let str = '123'
        return str;
      }
      
      const a = test(3) //string
      const b = test([1,2,3]) //string[]
      

      PlaygroundLink

      另见此问题:https://github.com/microsoft/TypeScript/issues/24929

      【讨论】:

        【解决方案3】:

        typescript 目前不支持基于联合的返回类型,但有解决此类问题的方法。

        function test<T extends number|number[]>(a: T):T extends number[] ? string[] : string {
          if (Array.isArray(a)) {
            return ['123', '45'] as any
          }
          return '123' as any
        }
        

        查看工作示例here

        更多详情请阅读 github 上的this issue

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-30
          • 1970-01-01
          • 1970-01-01
          • 2022-08-04
          • 2016-05-02
          • 2020-05-09
          • 2018-11-11
          相关资源
          最近更新 更多