Есть ли способ "извлечь" тип свойства интерфейса TypeScript?
Предположим, есть файл ввода для библиотеки X, который включает в себя некоторые интерфейсы.
interface I1 {
x: any;
}
interface I2 {
y: {
a: I1,
b: I1,
c: I1
}
z: any
}
Чтобы работать с этой библиотекой, мне нужно пройти вокруг объекта, который имеет тот же тип, что и I2.y
. Я могу, конечно, создать идентичный интерфейс в своих исходных файлах:
interface MyInterface {
a: I1,
b: I1,
c: I1
}
let myVar: MyInterface;
но затем я беру на себя обязательство постоянно обновлять его по сравнению с библиотекой, причем она может быть очень большой и приводить к большому количеству дублирования кода.
Следовательно, есть ли способ "извлечь" тип этого специфического свойства интерфейса? Что-то похожее на let myVar: typeof I2.y
(которое не работает и приводит к ошибке "Can not find name I2" ). Спасибо заранее.
Изменить: после небольшого воспроизведения в TS Playground я заметил, что следующий код достигает именно того, что я хочу:
declare var x: I2;
let y: typeof x.y;
Однако для этого требуется резервированная переменная x
. Я ищу способ добиться этого без этой декларации.
Ответы
Ответ 1
Это было невозможно, но, к счастью, это сейчас, так как TypeScript версия 2.1. Он был выпущен 7 декабря 2016 года и вводит индексированные типы доступа, также называемые типами поиска.
Синтаксис выглядит точно так же, как доступ к элементу, но написанный вместо типов. Итак, в вашем случае:
interface I1 {
x: any;
}
interface I2 {
y: {
a: I1,
b: I1,
c: I1
}
z: any
}
let myVar: I2['y']; // indexed access type
Теперь myVar
имеет тип I2.y
.
Посмотрите на TypeScript Игровая площадка.
Ответ 2
Интерфейс подобен определению объекта. Тогда y является свойством вашего объекта I2, который имеет определенный тип, в этом случае "анонимный".
Вы можете использовать другой интерфейс для определения y, а затем использовать его как ваш тип y, подобный этому
interface ytype {
a: I1;
b: I1;
c: I1;
}
interface I2 {
y: ytype;
z: any;
}
Вы можете поместить свой интерфейс в файл и использовать извлечение, чтобы вы могли импортировать его в другие файлы ваших проектов.
export interface ytype {
a: I1;
b: I1;
c: I1;
}
export interface I2 {
y: ytype;
z: any;
}
Вы можете импортировать его таким образом:
import {I1, I2, ytype} from 'your_file'