TypeScript 中的泛型类型参数 T 是什么?

What is a generic type parameter T in TypeScript?

正在浏览 TS 手册。 https://www.typescriptlang.org/docs/handbook/2/functions.html

In TypeScript, generics are used when we want to describe a correspondence between two values. We do this by declaring a type parameter in the function signature:

function firstElement<Type>(arr: Type[]): Type | undefined {
  return arr[0];
}

By adding a type parameter Type to this function and using it in two places, we’ve created a link between the input of the function (the array) and the output (the return value). Now when we call it, a more specific type comes out:

在这种情况下 Type 是关键字吗?当我看到 T 是同一件事吗?

我对这部分的理解正确吗?通过添加我们告诉 Typescript 将输入的任何类型分配给输出?

不是,这里Type是一个普通的标识符,它标识一个类型参数。通常类型参数以大写字母命名,如 T,但更具描述性的名称很有用。

此声明说:

function firstElement   // We are defining a function
         <Type>         // The function has a type parameter
         (arr: Type[]): // and regular parameters of that type.
         Type | undefined // It returns either a value of the type
                          // given by the type parameter, or undefined.

我们的想法是,您可以传递一个特定类型的元素数组,并期待一个相同类型的元素,静态检查:

firsElement<number>([1,2,3])会return一个number,编译器保证不会是字符串,也不会是对象

firstElement<number>(['a', 'b']) 甚至不会编译,因为它要求一个数字数组(通过 <number>),但收到一个字符串数组。

firstElement<number>([]) 将 return undefined,因为 return 没有第一个元素。 return 类型中的 | undefined 子句允许这样做。

In this case is Type a keyword?

在您的示例中,Typegeneric type parameter (type variable)

When I see just T is that the same thing?

假设令牌在同一位置,是的。

By adding we are telling Typescript to assign whatever type the input is to the output?

将它们类似于函数中的参数,但对于类型来说,这对我很有帮助。您实际上是在告诉打字稿:

“我正在创建一个名为 Type 的类型参数(变量)。我将在该函数中接受一个参数,该参数将是一个数组,您应该使用其中每个元素的类型数组作为代替 Type 的真实类型。我要 return 数组元素之一,因此此函数的 return 类型应与其中一个类型相同数组元素(如果我使用没有值的索引,则为 undefined)。

Now, there's one more potentially confusing part to this, based on the example that you provided, which is "Why doesn't TypeScript account for the possibility of undefined when indexing an array element using square brackets?", and that's covered in .

这是一个具体的例子:

TS Playground

function firstElement<Type>(arr: Type[]): Type | undefined {
  return arr[0];
}

// This type is: number[]
const arr1 = [1, 2, 3];

// When giving `arr1` as the argument to `firstElement`,
// `Type` will become `number` because each element in `arr1`
// is `number`. So the result will be: number | undefined
const result1 = firstElement(arr1);

// This type is: string[]
const arr2 = ['hello', 'world'];

// When giving `arr2` as the argument to `firstElement`,
// `Type` will become `string` because each element in `arr2`
// is `string`. So the result will be: string | undefined
const result2 = firstElement(arr2);

这是另一个使用 T 而不是 Type 作为通用类型参数的示例:

TS Playground

function elementAtIndex<T>(arr: T[], index: number): T | undefined {
  return arr[index];
}

const arr = ['zero', 'one', 'two'];

const zero = elementAtIndex(arr, 0); // string | undefined
console.log(zero); // "zero"

const three = elementAtIndex(arr, 3); // string | undefined
console.log(three) // undefined

FWIW, elementAtIndex in the example above is just a functional version of Array.prototype.at(), which should be in an upcoming release of TypeScript (probably v4.6).