Этот вопрос является прямым аналогом проверки типа класса с помощью TypeScript
Мне нужно выяснить во время выполнения, если переменная типа any реализует интерфейс. Вот мой код:
interface A{
member:string;
}
var a:any={member:"foobar"};
if(a instanceof A) alert(a.member);
Если вы введете этот код на игровой площадке, последняя строка будет помечена как ошибка: «Имя A не существует в текущей области». Но это не так, имя существует в текущей области видимости. Я даже могу изменить объявление переменной var a:A={member:"foobar"};
без жалоб от редактора. После просмотра веб-страниц и поиска другого вопроса по SO я изменил интерфейс на класс, но затем я не могу использовать литералы объектов для создания экземпляров.
Я задавался вопросом, как тип A мог исчезнуть таким образом, но взгляд на сгенерированный javascript объясняет проблему:
var a = {
member: "foobar"
};
if(a instanceof A) {
alert(a.member);
}
Нет представления A как интерфейса, поэтому проверки типа во время выполнения невозможны.
Я понимаю, что javascript как динамический язык не имеет понятия интерфейсов. Есть ли способ проверки типа для интерфейсов?
Автозаполнение игровой площадки показывает, что машинопись даже предлагает метод implements
. Как я могу использовать это?
Ответы:
Вы можете достичь того, чего хотите, без
instanceof
ключевого слова, так как теперь вы можете создавать собственные охранники типов:Много членов
Если вам нужно проверить множество членов, чтобы определить, соответствует ли объект вашему типу, вы можете вместо этого добавить дискриминатор. Ниже приведен самый базовый пример, который требует от вас управления вашими собственными дискриминаторами ... вам нужно углубиться в паттерны, чтобы избежать дублирования дискриминаторов.
источник
isInstanceOfA(instantiatedB)
вернуть true, но вы хотитеisInstanceOfB(instantiatedA)
вернуть false. Для того, чтобы последнее произошло, не должен ли дискриминатор B быть «Я-Я-А»?В TypeScript 1.6 пользовательский тип guard будет выполнять эту работу.
И точно так же, как упоминал Джо Янг: начиная с TypeScript 2.0, вы даже можете воспользоваться преимуществами тегового объединенного типа.
И это
switch
тоже работает .источник
object is type
иobject instanceof class
заключается в том, что тип в TypeScript является структурным, он заботится только о «форме», а не о том, откуда объект получил форму: обычный объект или экземпляр класса, это не имеет значения.type
свойством. В этом случае это работает. Этот пример не показывает этот факт.машинопись 2.0 ввести теговое объединение
Особенности Typescript 2.0
источник
Как насчет пользовательских типов охранников? https://www.typescriptlang.org/docs/handbook/advanced-types.html
источник
(pet as Fish).swim !== undefined;
.Теперь это возможно, я только что выпустил улучшенную версию
TypeScript
компилятора, которая предоставляет возможности полного отражения. Вы можете создавать экземпляры классов из их объектов метаданных, извлекать метаданные из конструкторов классов и проверять интерфейс / классы во время выполнения. Вы можете проверить это здесьПример использования:
В одном из ваших файлов машинописи создайте интерфейс и класс, который реализует его следующим образом:
Теперь давайте распечатаем список реализованных интерфейсов.
скомпилируйте с отражением и запустите его:
См. Mirror.d.ts для
Interface
деталей мета-типа.ОБНОВЛЕНИЕ: Вы можете найти полный рабочий пример здесь
источник
implements
но хотел признать ваше обязательство и не хотел бытьТо же, что и выше, где использовались определяемые пользователем средства защиты, но на этот раз с предикатом функции стрелки
источник
Вот еще один вариант: модуль ts-interface-builder предоставляет инструмент времени сборки, который преобразует интерфейс TypeScript в дескриптор времени выполнения, а ts-interface-checker может проверить, удовлетворяет ли объект этому.
Для примера OP,
Сначала вы запустите,
ts-interface-builder
который создаст новый краткий файл с дескриптором, скажемfoo-ti.ts
, который вы можете использовать так:Вы можете создать однострочную функцию защиты типа:
источник
Я хотел бы отметить, что TypeScript не предоставляет прямого механизма для динамического тестирования того, реализует ли объект конкретный интерфейс.
Вместо этого код TypeScript может использовать технику JavaScript для проверки наличия соответствующего объекта членов на объекте. Например:
источник
for (element in obj) {}
), чтобы убедиться, что два объекта имеют одинаковые элементы схожих типов.TypeGuards
источник
Основываясь на ответе Фентона , вот моя реализация функции, чтобы проверить, есть ли у данного
object
ключиinterface
, как полностью, так и частично.В зависимости от вашего варианта использования вам также может понадобиться проверить типы каждого из свойств интерфейса. Код ниже не делает этого.
Пример использования:
источник
источник
Поскольку тип неизвестен во время выполнения, я написал следующий код для сравнения неизвестного объекта не с типом, а с объектом известного типа:
Вот код (независимый от интерфейса), который я использую для глубокого сравнения:
Ниже приведен пример того, как я его использую.
В этом примере я ожидаю, что JSON содержит массив кортежей, вторым элементом которого является экземпляр интерфейса
User
(который имеет два необязательных элемента).Проверка типов в TypeScript обеспечит правильность моего образца объекта, а затем функция assertTypeT проверяет, что неизвестный (загруженный из JSON) объект соответствует объекту образца.
Вы можете вызвать такую проверку в реализации определяемой пользователем защиты типа.
источник
Вы можете проверить тип TypeScript во время выполнения, используя ts-validate-type , например так (хотя для этого требуется плагин Babel):
источник