Ignoruj ​​błędy maszynopisu „właściwość nie istnieje dla wartości typu”

227

W VS2013 budowanie zatrzymuje się, gdy tsc kończy działanie z kodem 1. Nie było tak w VS2012.

Jak mogę uruchomić moje rozwiązanie, ignorując błąd tsc.exe?

Otrzymuję wiele The property 'x' does not exist on value of type 'y'błędów, które chcę zignorować podczas korzystania z funkcji javascript.

Daniel
źródło

Odpowiedzi:

303

Wiem, że pytanie jest już zamknięte, ale znalazłem, że szuka tego samego wyjątku TypeScriptException, być może ktoś inny uderzył w to pytanie w poszukiwaniu tego problemu.

Problem polega na brakującym wpisywaniu TypeScript:

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

Rzuty The property 'getBBox' does not exist on value of type 'HTMLElement'.


Najprostszym sposobem jest jawne wpisanie zmiennej as any

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

Edycja, koniec 2016 r

Ponieważ preferowanym operatorem rzutowania TypeScript 1.6 jest to, że aste linie można przekształcić w elegancki:

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


Inne rozwiązania

Oczywiście, jeśli chcesz to zrobić dobrze, co czasami jest przesadą, możesz:

  1. Stwórz własny interfejs, który po prostu się rozszerza HTMLElement
  2. Wprowadź własne pisanie, które się rozszerza HTMLElement
michalczukm
źródło
14
Można również utworzyć interfejs, który rozszerza się HTMLElementi ma dodatkową getBBoxwłaściwość. W ten sposób nadal otrzymujesz uzupełnienie kodu dla innych właściwości.
thetallweeks
zamiast rzucać się na coś, czy getBBoxjest jakaś metoda rzetelnego rzucania? lubisz znaleźć rodzaj getBBox?
Pardeep Jain
FE: Jeśli getBBoxbyłby w HTMLElementtekście, możesz do niego rzucić obiekt var typedElement = <HTMLElement> outerHtmlElement;.
michalczukm
4
miły! var coordinates = (<any>outerElement[0]).getBBox();
bowpunya
1
To w rzeczywistości nie odpowiada na pytanie: „Jak zignorować błędy”
Petr Peller,
121

Szybkim i brudnym rozwiązaniem jest jawne przesłanie do any

(y as any).x

„Zaletą” jest to, że rzutowanie jest jawne, że kompiluje się nawet z noImplicitAnyustawioną flagą.

Właściwym rozwiązaniem jest aktualizacja pliku definicji typów.

Pamiętaj, że kiedy rzutujesz zmienną na any, rezygnujesz z sprawdzania typu tej zmiennej.


Ponieważ jestem w trybie wyłączenia odpowiedzialności, podwójne przesyłanie za pośrednictwem w anypołączeniu z nowym interfejsem może być przydatne w sytuacjach, w których Ty

  • nie chcę aktualizować uszkodzonego pliku pisma
  • łatają małpy

jednak nadal potrzebujesz formy pisania.

Załóżmy, że chcesz załatać definicję wystąpienia ytypu OrginalDefnową właściwością xtypu number:

const y: OriginalDef = ...

interface DefWithNewProperties extends OriginalDef {
    x: number
}

const patched = y as any as DefWithNewProperties

patched.x = ....   //will compile
Bruno Grieder
źródło
dzięki to pomogło: import http = wymagany („http”); serwer var = http jak dowolny; server.Server (aplikacja); // ignoruje błędy TS!
scape
Użyłem tego w „upewnij się, że nie znaleziono właściwości w NodeRequire”. więc zadeklarowałem moją zmienną wymaganą na NodeRequired i (wymagają jak każda) .ensure dla właściwości. Mam nadzieję że to pomoże.
Juni Brosas
61

Możesz także użyć następującej sztuczki:

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

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

Pamiętaj, że aby ponownie uzyskać dostęp do xbłędu maszynopisu, nie musisz go tak y["x"]pisać y.x. Z tego punktu widzenia inne opcje są lepsze.

Jarosław Jakowlew
źródło
4
Czy ktoś wie, dlaczego to działa i czy ma to jakiekolwiek potencjalne konsekwencje lub korzyści w porównaniu z początkowym zgłoszeniem obiektu jako :any?
mcheah
Przyniosłoby to wyraźną korzyść polegającą na zachowaniu czcionek, a nie na przesyłaniu. Chciałbym wiedzieć, dlaczego to nie rzuca ostrzeżenia, ale bezpośredni dostęp…
Powderham
38

Istnieje kilka sposobów rozwiązania tego problemu. Jeśli ten obiekt jest powiązany z jakąś biblioteką zewnętrzną, najlepszym rozwiązaniem byłoby znalezienie rzeczywistego pliku definicji ( tutaj świetne repozytorium ) dla tej biblioteki i odwołanie się do niego, np .:

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

Oczywiście nie dotyczy to w wielu przypadkach.

Jeśli chcesz „zastąpić” system typów, spróbuj wykonać następujące czynności:

declare var y;

Umożliwi to wykonywanie dowolnych połączeń var y.

Charles Marsh
źródło
5
Powinien być /// <reference path="/path/to/jquery.d.ts" />z tagiem samozamykającym na końcu
tic
Korzystam z VS2015 i postępowałem zgodnie z tym samouczkiem, jeśli nie mam jquery.d.tspliku w moim projekcie
Dimple
@Dimple npm install -g tsdzatemtsd install jquery
Akash
Druga opcja (deklaracja var y) działa świetnie, jeśli migrujesz z JavaScript do TypeScript i chcesz uniknąć błędu TS2304, ponieważ twój stary JavaScript odwołuje się do zmiennej w innym pliku JavaScript.
yesman
Dzięki! Dla mnie problem dotyczył Jest, const mockPrompt: any = jest.spyOn (step, 'prompt');
Mark Robson
18

Kiedy TypeScript myśli, że właściwość „x” nie istnieje na „y” , wtedy zawsze możesz rzutować „y” na „any”, co pozwoli ci wywoływać dowolne (np. „X”) na „y”.

Teoria

(<any>y).x;

Przykład ze świata rzeczywistego

Otrzymałem błąd „TS2339: Właściwość„ nazwa ”nie istnieje dla typu„ Funkcja ”dla tego kodu:

let name: string = this.constructor.name;

Naprawiłem to za pomocą:

let name: string = (<any>this).constructor.name;
Benny Neugebauer
źródło
1
Nie działa z super. Jeśli rozszerzysz klasę za pomocą pisma, a autor zapomni o metodzie publicznej, jesteś prawie zepsuty. Musisz dodać go do definicji typu, która zostaje zatrzymana przy kolejnej instalacji npm, zmuszając cię do utworzenia żądania ściągnięcia lub w inny sposób powiadomienia autora, co jest prawdopodobnie dobrą rzeczą, ale bólem.
Corey Alix,
15

Miałem problem w Angular2, korzystałem z lokalnego magazynu, aby coś zapisać i nie pozwoliło mi to.

Rozwiązania:

miałem localStorage.city -> error -> Property 'city' does not exist on type 'Storage'.

Jak to naprawić:

localStorage [„miasto”]

(localStorage) .city

(localStorage as any) .city

Avram Virgil
źródło
Druga opcja wygląda fajnie, ale wydaje się, że nie spełnia już swojej roli. Działa, jeśli poprzedzisz obiekt znakiem <any>- (<any>localStorage).city.
jayarjo
Wiem, że to jest stare, ale twój najlepszy przykład właśnie dla mnie zadziałał. Dobrze.
MacD
4

Szybka poprawka, w której nic innego nie działa:

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

Nie jest to dobra praktyka, ale zapewnia rozwiązanie bez konieczności wyłączania dosłowności

danday74
źródło
Robię to również, ale niektóre platformy (np. Google Cloud) wyświetlą komunikat ostrzegawczy sugerujący, że ab jest lepszy niż ['b']. Czy wiesz dlaczego tak jest?
Jonathan
1
Nie jestem pewien, ale możesz, na przykład w tslint.json, zmienić opcje tak, aby preferował ab
danday74
3

Wiem, że teraz jest 2020, ale nie widziałem odpowiedzi, która zaspokoi część „ignorowania” pytania. Okazuje się, że możesz powiedzieć TSLint, aby zrobił to tylko za pomocą dyrektywy;

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

Zwykle spowodowałoby to błąd stwierdzający, że „someProp nie istnieje na typie”. Z komentarzem ten błąd znika.

Zapobiegnie to zgłaszaniu błędów podczas kompilacji i powinno również powstrzymać Twoje IDE od narzekań.

Chwytak
źródło
0

W moim konkretnym projekcie nie mogłem go uruchomić i wykorzystałem declare var $;. Nie jest to czyste / zalecane rozwiązanie, nie rozpoznaje zmiennych JQuery, ale po użyciu tego nie miałem błędów (i musiałem, aby automatyczne kompilacje zakończyły się powodzeniem).

Niespokojny
źródło
0

Udało mi się to obejść na maszynie za pomocą czegoś takiego:

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);
}

Wydawało się, że to jedyny sposób, w jaki mogłem użyć wartości w X jako kluczy do mapy Y i kompilacji.

cs_pupil
źródło