首页 > 解决方案 > 打字稿在函数体中引用泛型 T

问题描述

如果我要将类型声明为单独的变量,例如:

type Foo =  <T>(x: T) => T 

然后用它来定义一个函数:

const foo:Foo = x => {
  let a = /*...*/
  /*...function execution...*/
  return a
}

如何T在函数体中引用泛型类型,例如声明变量a:T

标签: typescript

解决方案


您不能以任何方式引用此类型参数,因为它在类型声明中。它基本上是在说“你看,任何类型的函数Foo都是泛型的,你可以将类型参数传递给这种类型的任何函数,它的返回类型和参数将取决于这个类型参数”。T您在其中指定的这种类型参数Foo实际上并不存在,它只是向任何调用者发出信号,Foo表明它可以接受一个。

现在,您在编写类型函数的实际实现Foo时使用此参数。喜欢

type Foo = <T>(x: T) => T

const foo: Foo = <T>(x: T) => {
    let a: T = x
    return a
}

或者例如你可以用不同的方式命名它

type Foo = <T>(x: T) => T

const foo: Foo = <U>(x: U) => {
    let a: U = x
    return a
}

Foo类型不强制执行任何操作,它只是说“此函数有 1 个类型参数”,并且该函数可以根据需要调用和使用此参数。甚至可以完全忽略它

type Foo = <T>(x: T) => T

const foo: Foo = () => {
  return 5 as any
}

同样,就函数的调用者而言,foo接受一个类型参数只是因为foo它是该Foo类型的实现,即使foo实际上并未使用它。

或者您可以添加一个可选的额外类型参数和此类型的可选变量

type Foo = <T>(x: T) => T

const foo: Foo = <U, K = number>(x: U, y?: K) => {
    if(y) console.log(y)

    let a: U = x
    return a
}

这仍然有效,因为任何调用foo的人都可以查看类型定义并看到“好的,Foo接受 1 个类型参数和 1 个普通参数”。如果他们现在提供 1 个类型参数和 1 个普通参数,它仍然可以工作,因为foo在这种情况下可以正常工作。


推荐阅读