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

标签 typescript typescript-generics

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

然后在 typescript 代码库中找到了这个类似的代码:
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]>;
}

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

在 typescript 手册示例中,它说

the element type of the array as T[number]



在操场上测试时(仅用于测试),替换 T[number]TT[any]好像没什么区别,但是不能用T[string]代替(为什么?)。
[number]之后 T似乎不是索引。

最佳答案

Array使用 index signature 声明,像这样:

interface ArrayMaybe<Element> {
    [index: number]: Element;
}

(我叫这个 ArrayMaybe 因为我没有特意复制 Array 的声明,和它无关。)

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

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

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

对于字符串索引签名的示例,请考虑
interface Dictionary<Value> {
    [key: string]: Value;
}

有了这个,我们可以使用 T[string]T是一些 Dictionary ——和 T[string]将是 Value .

综上所述,我个人更喜欢使用专用的环境类型来引用数组的元素,如下所示:
type ElementOf<T extends unknown[] | readonly unknown[]> = T[number];

然后从那时起您就可以使用 ElementOf<T>而不是 T[number] .我发现这比使用 T[number] 更具可读性和清晰性.

关于typescript - typescript 代码中的 T[number] 是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59187941/

相关文章:

javascript - 从 `void` 函数返回 `async`

node.js - 如何输入自定义异步 Express 处理程序,以便透明地传递通用类型参数

typescript 如何从常量属性值推断类型

typescript - 实例化类的通用 TypeScript 函数

typescript - 是否可以根据传入的对象推断对象类型?

javascript - typescript 装饰器只能在同一个方法中工作

typescript - 相同属性的 setter 和 getter 引起 eslint 签名应该是相邻错误

node.js - 参数类型 "X"不可分配给参数类型 "Y"

typescript - 如何从字符串数组中推断对象键的类型

typescript - 在 TypeScript 中获取递归属性的联合类型