На самом деле я даже не знаю, как правильно сформулировать вопрос. Из генератора кода я получаю следующий интерфейс в качестве ввода для запроса API:
interface foo {
bar: ('foo' | 'bar')[]
}
Чтобы получить доступ к этому, я могу создать псевдонимы, такие как type xy = foo['bar']
. Но на самом деле я понятия не имею, как получить тип, включающий объединение внутри массива. Я хочу иметь тип type union = 'foo' | 'bar'
, ссылаясь на интерфейс.
Я уже пытался использовать аннотацию индекса, например type union = foo['bar'][string]
или type union = foo['bar'][number]
, но это выдает ошибку.
Вы можете сделать это, обратившись к свойству bar
через нотацию доступа к свойствам интерфейса: foo["bar"]
, а затем получить доступ к объединению элементов, проиндексировав их с помощью number
, чтобы получить тип элементов. Вот полный код:
interface foo {
bar: ('foo' | 'bar')[]
}
type FooBarItem = foo["bar"][number];
// ^? "bar" | "foo"
Обновление на основе новая информация, которую вы представили:
Поскольку это свойство является необязательным, вы можете использовать утилиту типов NonNullable<Type>
, чтобы исключить null
и undefined
из его объединения. Затем вы можете использовать индексированный тип доступа (number
в данном случае для доступа к элементам в массиве, которые индексируются с помощью цифровых клавиш).
interface Foo {
bar?: ('foo' | 'bar')[];
}
type BarOrFoo = NonNullable<Foo['bar']>[number]; // "bar" | "foo"
Ну, на самом деле проблема, с которой я столкнулся, была немного другой и отсутствует в моем примере.
Если у вас есть
interface Foo {
bar?: ('foo' | 'bar')[]
}
Тогда type BarOrFoo = Foo['bar'][number]; // "bar" | "foo"
не получится.
Но вместо этого работает следующее
type BarOrFoo = Exclude<Foo['bar'], undefined>[number]
Информация о новом вопросе относится к содержанию вопроса.