Ігнорувати помилки машинопису "властивість не існує у значенні типу"


227

У VS2013 будівництво припиняється, коли tsc виходить із кодом 1. У VS2012 цього не було.

Як я можу запустити своє рішення, ігноруючи помилку tsc.exe?

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

Відповіді:


303

Я знаю, що питання вже закрите, але я виявив, що шукає той же 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

14
Ви також можете створити інтерфейс, який розширюється HTMLElementта має додаткову getBBoxвластивість. Таким чином, ви все одно отримаєте завершення коду для інших властивостей.
thetallweeks

замість того, getBBoxщоб кидати його в будь- який спосіб, чи є метод, який потрібно швидко робити? Ви хочете дізнатися тип getBBox?
Pardeep Jain

FE: Якщо ти getBBoxбудеш HTMLElementтипом, ти можеш кинути йому об'єкт var typedElement = <HTMLElement> outerHtmlElement;.
michalczukm

4
приємно! var coordinates = (<any>outerElement[0]).getBBox();
боупуня

1
Це насправді не відповідає на запитання: "Як ЗНАЙТИ помилки"
Петро Пеллер

121

Швидке та брудне рішення - це чітко вказати 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

завдяки цьому допомогло: імпортувати http = need ('http'); var server = http як будь-який; сервер.сервер (додаток); // ігнорує ts помилки!
скап

Я використовував це в "забезпечити властивість не знайдено в NodeRequire". тому я оголосив свою змінну потребу на NodeRequired та (вимагаю як будь-яку) .забезпечення властивості. Сподіваюсь, це допомагає.
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

@Dimple npm install -g tsdтодіtsd install jquery
Акаш

Другий варіант (оголосити var y) чудово працює, якщо ви переходите з JavaScript на TypeScript і хочете уникнути помилки TS2304, оскільки ваш старий JavaScript посилається на змінну в іншому файлі JavaScript.
yesman

Дякую! Для мене проблема була з Jest, const mockPrompt: any = jest.spyOn (step, 'prompt');
Марк Робсон

18

Коли TypeScript вважає, що властивість "x" не існує на "y" , то ви завжди можете передавати "y" в "будь-яке", що дозволить вам викликати що-небудь (наприклад, "x") на "y".

Теорія

(<any>y).x;

Приклад реального світу

Я отримував помилку "TS2339: Властивість" ім'я "не існує для типу" Функція "для цього коду:

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.
jayarjo

Я знаю, що це старе, але твій найкращий приклад просто працював для мене .. Молодці.
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


Я теж це роблю, але деякі платформи (наприклад, Google Cloud) піднімуть попереджувальне повідомлення про те, що ab кращий, ніж ['b']. Ви знаєте, чому це?
Джонатан

1
Не впевнений, але ви можете, наприклад, у tslint.json змінити параметри, щоб він
вважав за

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 та компіляції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.