关于基于输入参数的泛型返回类型的困惑

时间:2021-02-20 12:57:04

标签: 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

1 个答案:

答案 0 :(得分:0)

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

例3的问题是返回的数组(<html> <head> <title>Cascading Selects</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> </head> <body> <h2>Console Picker/Store</h2> <div id="selectsDiv"></div> <script src="selectData.js"></script> <script src="createSelects.js"></script> </body> </html>)与指定的返回类型不匹配,如果数组类型是string [],而T[]本身不能匹配是字符串类型。它可以扩展字符串类型。此外,必须使用绑定参数类型来让参数类型 T 匹配返回类型。您不必为结果重新声明类型参数 T

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

T

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