Pytanie TypeScript - użyj poprawnej wersji setTimeout (node ​​vs window)


Pracuję nad uaktualnieniem starego kodu TypeScript, aby użyć najnowszej wersji kompilatora, i mam problem z wywołaniem setTimeout. Kod spodziewa się zadzwonić do przeglądarki setTimeout funkcja, która zwraca liczbę:

setTimeout(handler: (...args: any[]) => void, timeout: number): number;

Jednak kompilator rozwiązuje to do implementacji węzła, która zwraca NodeJS.Timer:

setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;

Ten kod nie działa w węźle, ale typowanie węzła jest pobierane jako zależność od czegoś innego (nie wiem co).

Jak mogę polecić kompilatorowi wybranie wersji setTimeout to chcę?

Oto kod w pytaniu:

let n: number;
n = setTimeout(function () { /* snip */  }, 500);

Powoduje to błąd kompilatora:

TS2322: Typ "Timer" nie może być przypisany do "numeru".


11
2017-08-21 17:49


pochodzenie


Czy masz typ: ["node"] w twoim tsconfig.json? Widzieć stackoverflow.com/questions/42940954/... - koe
@koe Nie, nie mam typów: ["węzeł"] opcji w pliku tsconfig. Ale typy węzłów są pobierane jako zależność npm od czegoś innego. - Kevin Tighe
Możesz także jawnie zdefiniować "typy" w tsconfig.json - gdy pominiesz "węzeł", nie będzie on używany w kompilacji. na przykład "types": ["jQuery"] - koe


Odpowiedzi:


Zmierzyłem się z tym samym problemem i obejście, które nasz zespół zdecydował się użyć, było po prostu użyć "any" dla typu timera. Na przykład.:

let n: any;
n = setTimeout(function () { /* snip */  }, 500);

Będzie działać z obydwoma implementacjami metod setTimeout / setInterval / clearTimeout / clearInterval.


3
2017-08-21 20:12



Tak, to działa. Zdałem sobie również sprawę, że mogę po prostu określić metodę bezpośrednio na obiekcie okna: window.setTimeout (...). Nie jestem pewien, czy to najlepszy sposób, ale na razie będę go trzymać. - Kevin Tighe
Możesz zaimportować przestrzeń nazw NodeJS poprawnie w maszynopisie, patrz ta odpowiedź. - hlovdal
Aby właściwie odpowiedzieć na pytanie ("jak mogę polecić kompilatorowi, aby wybrał żądaną wersję"), można użyć window.setTimeout () zamiast, jak @dhilt odpowiedział poniżej. - Anson VanDoren


Inne obejście, które nie wpływa na deklarację zmiennej:

let n: number;
n = <any>setTimeout(function () { /* snip */  }, 500);

Powinno również być możliwe użycie window obiekt jawnie bez any:

let n: number;
n = window.setTimeout(function () { /* snip */  }, 500);

6
2018-05-19 18:40