Получение типа элементов массива с учетом типа массива в TypeScript - PullRequest
0 голосов
/ 07 мая 2020

Я пишу общую c функцию в TypeScript, и я не могу найти способ извлечь тип элементов массива с учетом типа массива. Допустим, у меня есть такие данные:

interface Store {
    posts: Post[]
    users: User[]
}

const store: Store = {
    posts: [post0, post1, post2],
    users: []
}

, и моя функция принимает эти массивы и что-то с ними делает, скажем, возвращает первый элемент, когда что-то внутри.

function process<T>(storeItem: T[]): T | null {
    if (storeItem) return storeItem[0]
    return null
}

Теперь я хочу создать новую функцию, которая применяет эту функцию ко всем элементам магазина по очереди и создает новый объект. Эта функция выглядит как

const processed = Object.keys(store).reduce((accum, el) => {...accum, process(store[el])}, {})

Теперь я хочу определить тип результирующего объекта processed как

type Processed<Store> = {
    [K in keyof Store]: ArrayElement<Store[K]> | null
}

, но я не могу найти способ извлечь тип элементов массива с учетом типа массива, т.е. что-то эквивалентное ArrayElement (это то, что я придумал). Как я мог это обойти?

1 Ответ

0 голосов
/ 07 мая 2020

Я нашел решение здесь в примере расширенных типов.

type Unpacked<T> =
    T extends (infer U)[] ? U :
    T extends (...args: any[]) => infer U ? U :
    T extends Promise<infer U> ? U :
    T;

type T0 = Unpacked<string>;  // string
type T1 = Unpacked<string[]>;  // string
type T2 = Unpacked<() => string>;  // string
type T3 = Unpacked<Promise<string>>;  // string
type T4 = Unpacked<Promise<string>[]>;  // Promise<string>
type T5 = Unpacked<Unpacked<Promise<string>[]>>;  // string

Итак, самым простым решением для моего случая было бы определение моего типа ArrayElement как:

type ArrayElement<T> = T extends (infer U)[] ? U : null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...