Игнорировать ошибки Typescript «свойство не существует для значения типа»

228

В VS2013 здание останавливается, когда TSC выходит с кодом 1. Это не было в VS2012.

Как я могу запустить свое решение, игнорируя ошибку tsc.exe?

Я получаю много The property 'x' does not exist on value of type 'y'ошибок, которые я хочу игнорировать при использовании функций JavaScript.

Даниил
источник

Ответы:

304

Я знаю, что вопрос уже закрыт, но я обнаружил, что он ищет то же исключение TypeScriptException, возможно, кто-то еще задал этот вопрос в поисках этой проблемы.

Проблема заключается в отсутствии ввода TypeScript:

var coordinates = outerElement[0].getBBox();

Броски The property 'getBBox' does not exist on value of type 'HTMLElement'.


Самый простой способ - явно указать переменную как any

var outerHtmlElement: any = outerElement[0];
var coordinates = outerHtmlElement.getBBox();

Редактировать, конец 2016

Поскольку предпочтительным оператором приведения является TypeScript 1.6, asэти строки можно сжать до элегантного:

let coordinates = (outerElement[0] as any).getBBox();


Другие решения

Конечно, если вы хотите сделать это правильно, что иногда является излишним, вы можете:

  1. Создайте собственный интерфейс, который просто расширяется HTMLElement
  2. Введите собственный набор текста, который расширяет HTMLElement
michalczukm
источник
14
Вы также можете создать интерфейс, который расширяется HTMLElementи имеет дополнительное getBBoxсвойство. Таким образом, вы по-прежнему получаете завершение кода для других свойств.
thetallweeks
вместо того, чтобы бросать в любой, getBBoxесть ли способ, чтобы бросить в порядке? хотели бы узнать тип getBBox?
Пардип Джейн
FE: Если getBBoxбы вы были в HTMLElementтипе, вы могли бы привести объект к нему var typedElement = <HTMLElement> outerHtmlElement;.
michalczukm
4
отлично! var coordinates = (<any>outerElement[0]).getBBox();
бапуня
1
Это фактически не отвечает на вопрос: «Как игнорировать ошибки»
Петр Пеллер,
123

Быстрое и грязное решение - явное приведение к any

(y as any).x

«Преимущество» состоит в том, что при явном приведении это будет компилироваться даже с установленным noImplicitAnyфлагом.

Правильным решением является обновление файла определения набора текста.

Обратите внимание, что когда вы приводите переменную к any, вы отказываетесь от проверки типа для этой переменной.


Поскольку я нахожусь в режиме отказа от ответственности, двойное приведение в anyсочетании с новым интерфейсом может быть полезно в ситуациях, когда вы

  • не хотите обновлять испорченный файл
  • исправления обезьяны

тем не менее, вы все еще хотите некоторую форму ввода.

Допустим, вы хотите исправить определение экземпляра yтипа OrginalDefновым свойством xтипа number:

const y: OriginalDef = ...

interface DefWithNewProperties extends OriginalDef {
    x: number
}

const patched = y as any as DefWithNewProperties

patched.x = ....   //will compile
Бруно Гридер
источник
Спасибо, это помогло: import http = require ('http'); var server = http как любой; server.Server (приложение); // игнорирует ошибки ts!
Сценарий
Я использовал это в "убедиться, что свойство не найдено в NodeRequire". поэтому я объявил свою переменную require в NodeRequired и (require как any) .ensure для свойства. Надеюсь это поможет.
Juni Brosas
61

Вы также можете использовать следующий трюк:

y.x = "some custom property"//gives typescript error

y["x"] = "some custom property"//no errors

Обратите внимание: чтобы получить доступ xк ошибке машинописания и не получить ее снова, нужно написать ее так y["x"], а не так y.x. Так что с этой точки зрения другие варианты лучше.

Ярослав Яковлев
источник
4
Кто-нибудь знает, почему это работает, и имеет ли это какие-либо потенциальные последствия или преимущества по сравнению с первоначальным объявлением объекта как :any?
mcheah
Было бы явным преимуществом сохранять наборы, а не приведение к любому. Я хотел бы знать, почему это не
Powderham
38

Есть несколько способов справиться с этой проблемой. Если этот объект связан с какой-то внешней библиотекой, лучшим решением было бы найти фактический файл определений (большой репозиторий здесь ) для этой библиотеки и сослаться на него, например:

/// <reference path="/path/to/jquery.d.ts" >

Конечно, это не относится во многих случаях.

Если вы хотите переопределить систему типов, попробуйте следующее:

declare var y;

Это позволит вам делать любые звонки по вашему желанию var y.

Чарльз Марш
источник
5
Должен быть /// <reference path="/path/to/jquery.d.ts" />с самозакрывающимся тегом в конце
тик
Я использую VS2015 и следовал этому уроку для угловых у меня нет jquery.d.tsфайла в моем проекте
Dimple
@ Димпл npm install -g tsdтогдаtsd install jquery
Акаш
Второй вариант (объявлять переменную) прекрасно работает, если вы переходите с JavaScript на TypeScript и хотите избежать ошибки TS2304, поскольку ваш старый JavaScript ссылается на переменную в другом файле JavaScript.
Yesman
Спасибо! Для меня проблема была с Jest, const mockPrompt: any = jest.spyOn (step, 'prompt');
Марк Робсон
18

Когда TypeScript считает, что свойство «x» не существует в «y» , тогда вы всегда можете преобразовать «y» в «any», что позволит вам вызывать что угодно (например, «x») для «y».

теория

(<any>y).x;

Пример из реального мира

Я получаю сообщение об ошибке "TS2339: свойство 'name' не существует для типа 'Function'" для этого кода:

let name: string = this.constructor.name;

Поэтому я исправил это с помощью:

let name: string = (<any>this).constructor.name;
Бенни Нойгебауэр
источник
1
Не работает с супер. Если вы расширяете класс, используя типизацию, а автор забывает публичный метод, вы в значительной степени облажались. Вы должны добавить его в определение типа, которое останавливается при следующей установке npm, вынуждая вас создавать запрос на извлечение или иным образом уведомлять автора, что, вероятно, хорошо, но неприятно.
Кори Аликс
15

У меня была проблема в Angular2, я использовал локальное хранилище, чтобы что-то сохранить, и это не позволило мне.

Решения:

я имел localStorage.city -> error -> Property 'city' does not exist on type 'Storage'.

Как это исправить:

LocalStorage [ 'город']

(LocalStorage) .city

(localStorage как любой) .city

Аврам Вирджил
источник
Второй вариант выглядит круто, но, похоже, больше не справляется с этой задачей. Работает, если вы префикс объекта <any>- (<any>localStorage).city.
Джаярджо
Я знаю, что это старый, но ваш лучший пример работал на меня .. Молодцы.
MacD
4

Быстрое исправление, где больше ничего не работает:

const a.b = 5 // error

const a['b'] = 5 // error if ts-lint rule no-string-literal is enabled

const B = 'b'
const a[B] = 5 // always works

Не очень хорошая практика, но предоставляет решение без необходимости выключать no-string-literal

danday74
источник
Я тоже так делаю, но некоторые платформы (например, Google Cloud) выдают предупреждающее сообщение о том, что ab лучше, чем ['b']. Ты знаешь почему это?
Джонатан
1
Не уверен, но вы можете, например, в tslint.json изменить параметры так, чтобы они предпочитали ab
danday74
3

Я знаю, что сейчас 2020, но я не смог найти ответ, который удовлетворил бы «игнорирующую» часть вопроса. Оказывается, вы можете сказать TSLint сделать это, используя директиву;

// @ts-ignore
this.x = this.x.filter(x => x.someProp !== false);

Обычно это выдает ошибку, утверждая, что «someProp не существует для типа». С комментарием эта ошибка исчезает.

Это остановит любые ошибки, возникающие при компиляции, а также остановит жалобу вашей IDE на вас.

Льюис
источник
0

В моем конкретном проекте я не мог заставить его работать, и использовал declare var $;. Не чистое / рекомендованное решение, оно не распознает переменные JQuery, но у меня не было ошибок после его использования (и пришлось, чтобы мои автоматические сборки были успешными).

похотливый
источник
0

Я смог обойти это в машинописи, используя что-то вроде:

let x = [ //data inside array ];
let y = new Map<any, any>();
for (var i=0; i<x.length; i++) {
    y.set(x[i], //value for this key here);
}

Казалось, это единственный способ, которым я мог использовать значения внутри X в качестве ключей для карты Y и компилировать.

cs_pupil
источник