【问题标题】:Confusion about generic return type based on input parameters基于输入参数的泛型返回类型的混淆
【发布时间】:2021-02-21 03:26:25
【问题描述】:

我将展示几个 withwithout 泛型返回类型的示例,我很困惑为什么 typescript 不处理所有示例一样。

示例 1:基本情况 - 函数重载(正常工作)

function test(data:string):string
function test(data:string[]):string[]
function test(data:string | string[]): string | string[] {

  if(Array.isArray(data)){
     return ['']
  } 

  return data
}

const testArr = test([]) // return type is Array
const testStr=test('a') // return type is string

现在我将尝试对 generic 数据类型做同样的事情:

示例 2:从函数推断的返回类型错误

function testGeneric<T extends string | string[]>(data:T){
  if(Array.isArray(data)){
     return ['']
  } 

  return data
}

const testArrGen = testGeneric([])
const testStrGen=testGeneric('a')

示例 3:函数本身的返回类型错误。

function testGeneric2<T extends string | string[]>(data:T): T extends string? T : T[]{
  if(Array.isArray(data)){
     return [''] // error
  } 

  return data // error
}

const testArrGen2 = testGeneric2([]) // string[] || never[]
const testStrGen2=testGeneric2('a') //  "a"| string[]

现在我想了解为什么示例 23 是错误的,以及如何使用泛型创建正确的实现。

TS Playground

【问题讨论】:

  • this 回答你的问题了吗?

标签: typescript


【解决方案1】:

在示例 2 中,没有为结果声明类型信息,也没有对结果进行类型推断。

示例 3 的问题是返回的数组 (string []) 与指定的返回类型不匹配,在数组类型为 T[] 的情况下,T 本身不能是字符串类型。它可以扩展字符串类型。此外,必须使用绑定参数类型来让参数类型T 匹配返回类型。您不必为结果重新声明类型参数T

我认为它应该是这样工作的:

function testGeneric2<T extends string | string[]>(data: T): T {
  if (Array.isArray(data)) {
    const res: T = Object.create(data);

    return res;
  }

  return data;
}

由于无法从开箱即用的类型参数创建新对象(请参阅here),我使用 Object.create 从数组参数创建了一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 2019-06-07
    • 2015-05-09
    • 1970-01-01
    • 2021-11-10
    相关资源
    最近更新 更多