Как получить тип значений типа массива?

Если у меня есть тип type foo = Array<{ name: string; test: number; }>, можно ли получить тип значений в массиве, в этом случае интерфейс. Я знаю, что есть keyof, чтобы получить ключи, есть ли что-то подобное для значений?

Ответ 1

Если вы хотите узнать, как извлечь тип { name: string; test: number; }, вы можете просто создать псевдоним для элемента по индексу:

type Foo = Array<{ name: string; test: number; }>;
type FooItem = Foo[0];

или

type FooItem = Foo[number];

Ответ 2

Начиная с TypeScript 2.8, вы также можете сделать это с ключевым словом infer:

type GetElementType<T extends Array<any>> = T extends (infer U)[] ? U : never;

Например:

// ElementType === string
type ElementType = GetElementType<string[]>;

И это также работает внутри отображаемых типов, где разные свойства могут иметь разные типы:

type MapArraysToValues<T extends { [key: string]: any[] }> = {
    [key in keyof T]: GetElementType<T[key]>;
};

// Output === { x: number, y: string }
type Output = MapArraysToValues<{ x: number[], y: string[] }>;

Ответ 3

Несмотря на ответ Алексея, было бы полезно знать, что если экземпляр этого родового типа предоставляет хотя бы одного члена типа, который вы хотите извлечь, вы можете использовать typeof to запросить тип этого элемента.

Для общего Array тип может быть запрошен из любого элемента массива: введите описание изображения здесь

Обратите внимание, что строка 27 существует только во время разработки, чтобы не создавать никаких ошибок, даже если arr пуст или undefined во время выполнения.

Ответ 4

Мы также можем использовать индексированный оператор доступа следующим образом:

const someArray = [
    {
        foo: '',
        bar: '',
        baz: ''
    },
    {
        foo: '',
        bar: '',
        baz: ''
    }
];

// indexed access operator
type SomeArray = typeof someArray[number];

О них можно узнать здесь: https://www.typescriptlang.org/docs/handbook/advanced-types.html.

Второй оператор - T [K], оператор индексированного доступа.