打字稿代码中的 T[number] 是什么意思?

db9*_*035 6 typescript typescript-generics

首先在http://www.typescriptlang.org/docs/handbook/advanced-types.html#example-1 中找到了代码

然后在打字稿代码库中找到了这个类似的代码:https : //github.com/microsoft/TypeScript/blob/master/tests/cases/conformance/types/conditional/conditionalTypes1.ts#L75

type KnockoutObservable<T> = { object: T };
type KnockoutObservableArray<T> = { array: T };

type KnockedOut<T> = T extends any[] ? 
                       KnockoutObservableArray<T[number]> : 
                       KnockoutObservable<T>;

type KnockedOutObj<T> = {
    [P in keyof T]: KnockedOut<T[P]>;
}
Run Code Online (Sandbox Code Playgroud)

代码中的 T[number] 是什么意思?

在打字稿手册示例中,它说

数组的元素类型为 T[number]

在操场上测试时(仅用于测试),替换T[number]TT[any]似乎没有什么不同,但不能替换为T[string](为什么?)。

[number]T,似乎不是一个索引。

KRy*_*yan 9

Array使用索引签名声明,如下所示:

interface ArrayMaybe<Element> {
    [index: number]: Element;
}
Run Code Online (Sandbox Code Playgroud)

(我这样称呼ArrayMaybe是因为我没有专门复制Array的声明,而且它不相关。)

索引签名表明一个类型可以具有使用该类型的任何值作为键或索引的属性,但在每个这样的键/索引处具有相同类型的值。SoArrayMaybe<number>可以有值 at 0142,等等,但只要有这样的属性,属性的值就会是 a number

另一方面,在谈论某种类型时T,会T[____]引用 的某些特定属性T。所以{ foo: 'bar'; }['foo']会提到 type 'bar'。在我们上面看到的索引签名的情况下,我们可以使用T[number]来引用该索引签名的类型——在 的情况下ArrayMaybe,即Element。这正是它在您的示例中的使用方式。

您不能使用,T[string]因为Array没有字符串索引签名。你可以使用这些,但Array不能。由于它没有字符串索引签名,T[string]因此不合法。T['length']不过,您可以使用,因为Array确实有一个带有该字符串的属性。使用stringnumber引用任何需要索引签名的字符串或数字。

对于字符串索引签名的示例,请考虑

interface Dictionary<Value> {
    [key: string]: Value;
}
Run Code Online (Sandbox Code Playgroud)

有了这个,我们可以使用T[string]when Tis some Dictionary—and T[string]will be Value


综上所述,我个人更喜欢使用专用的环境类型来引用数组的元素,如下所示:

type ElementOf<T extends unknown[] | readonly unknown[]> = T[number];
Run Code Online (Sandbox Code Playgroud)

然后从那时起您可以使用ElementOf<T>代替T[number]. 我发现它比使用T[number].