Я хочу извлечь подтип из интерфейса в машинописном тексте, как показано ниже.
interface components {
schemas: {
a: {
b?: Array<{
c?: {
d?: string;
};
}>;
};
}
// I want to export
export type custom = components["schemas"]["a"]["b"][number]["c"]
однако я получаю сообщение об [number]ошибкеType '{ c?: { d?: string | undefined; } | undefined; }[] | undefined' has no matching index signature for type 'number'.ts(2537)
Как мы этого добиваемся?
Решение проблемы
Вот что я придумал:
type Increment<A extends number[]> = [...A, 0];
type DeepRequired<T, D extends number = -1, R extends number[] = []> =
T extends object? R["length"] extends D? T: {
[K in keyof T]-?: DeepRequired<T[K], D, Increment<R>>;
}: T;
Давайте посмотрим DeepRequiredбез лишних битов:
type DeepRequired<T> = T extends object? {
[K in keyof T]-?: DeepRequired<T[K]>;
}: T;
Этот тип прост по своей сути; это просто обход всего объекта и создание всех необходимых свойств.
Это работает без ошибок:
type T = DeepRequired<components>["schemas"]["a"]["b"][number]["c"];
Но вы заметите T, что свойство "d" также требуется, что может не дать желаемого результата. Вот почему это намного сложнее; он ограничивает глубину, на которой он делает требуемые свойства.
Вернемся к нашему исходному фрагменту: создается тип утилиты Incrementдля увеличения глубины, на которой мы находимся, а новые параметры DeepRequiredвключают указанную глубину (необязательно) и текущую глубину, на которой она находится.
Прежде чем сделать все необходимые свойства, он проверяет, не превышает ли он указанную глубину, и если это так, он останавливается.
Теперь это работает так, как ожидалось:
type T = DeepRequired<components, 5>["schemas"]["a"]["b"][number]["c"];
Детская площадка
Комментариев нет:
Отправить комментарий