Typescript: setTimeout - Das Zuweisen einer Timeout-ID zu einer Variablen löst einen Fehler aus. TS2323: Der Typ 'Timer' kann nicht dem Typ 'number' zugewiesen werden.

Erstellt am 7. Okt. 2014  ·  24Kommentare  ·  Quelle: microsoft/TypeScript

Bei Verwendung von tsc v1.1.0-1 wird beim Kompilieren eine Fehlermeldung angezeigt:
Fehler TS2323: Der Typ 'Timer' kann nicht dem Typ 'Nummer' zugewiesen werden.

Der folgende Code löst den Kompilierungsfehler aus:

this.sTimeout = setTimeout (() => this.showDelay (), 250);

sTimeout ist als Zahl (private Variable) definiert.

Question

Hilfreichster Kommentar

Verwenden Sie stattdessen einfach window.setTimeout .

Alle 24 Kommentare

Bitte posten Sie ein vollständiges Beispiel. Die bisher gegebenen Informationen reichen nicht aus, um das Problem zu reproduzieren:

class Foo {
    private sTimeout: number;
    showDelay() { }
    bar() {
        setTimeout(() => this.showDelay(), 250);
    }
}

Es gibt keinen integrierten Typ mit dem Namen Timer daher ist es wahrscheinlich, dass die setTimeout Ihnen angerufenen window.setTimeout .

Hätte ein Beispiel geben sollen - war etwas früher gehetzt. Bitte schön:

class Foo {
    private sTimeout: number; // Storing Timeout ID - to clear it - if needed
    private showDelay() { }
    constructor() {
        this.sTimeout = setTimeout(() => this.showDelay(), 250);
    }
}

Wirft den folgenden Fehler:

Verwenden von tsc v1.1.0-1
/tests/Foo.ts(5,3): Fehler TS2323: Der Typ 'Timer' kann nicht dem Typ 'Nummer' zugewiesen werden.

Im Moment habe ich es behoben, indem ich sTimeout auf any eingegeben habe.

Das ist für mich kein Vorwurf. Was passiert, wenn Sie F12 setTimeout ?

Nicht sicher, was du mit F12 meinst? .

"Zur Definition gehen"

Auch hier gibt es keinen integrierten Typ namens Timer , daher muss sich Ihr Code auf einen anderen Typ beziehen. Bitte probieren Sie Ihr Beispiel in einer Datei selbst aus oder finden Sie heraus, woher in Ihrem Projekt dieses Timer stammt. Ich vermute, dass sich setTimeout nicht auf die integrierte Funktion bezieht, sondern auf eine andere benutzerdefinierte Funktion, die einen anderen Rückgabewert hat.

Ich habe das Beispiel selbst ausprobiert: Es scheint, als würde es durch eine Komponente in meiner Toolchain oder einen anderen Code verursacht - entschuldigen Sie, dass Sie sich Zeit genommen haben. Danke ... Geschlossen ...

Für zukünftige Leser bin ich auf diesen Fehler aufgrund der definitiv typisierten Definitionen von node.j gestoßen. Die Lösung besteht darin, den vollständigen Namen des Typs zu verwenden, der NodeJS.Timer nicht Timer (was leider vom Typescript-Transpiler vorgeschlagen wird und nicht funktioniert).

@jdfreder die Zeit

Trotzdem hatte ich das gleiche Problem: error TS2352: Neither type 'Timer' nor type 'number' is assignable to the other. , obwohl ich die implizite Referenz oben in der Datei definiert habe /// <reference path="node_modules/typescript/lib/lib.d.ts" /> funktioniert immer noch nicht.

Das Hauptproblem besteht darin, dass in einem unserer npm-Pakete von Drittanbietern (angle2) TS + -Typisierungen (Knoten und andere) im Paket enthalten sind.

@rixrix (und für alle anderen, die dies finden) Ich hatte ein ähnliches Problem, bis mir klar wurde, dass ich nicht die richtigen Parameter übergab.

Vergleichen Sie dies, was den zweiten Parameter ms erfordert und ein NodeJS.Timer zurückgibt:

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

... und dies macht den zweiten Parameter timeout optional und gibt ein number :

function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

Basierend auf diesen beiden Funktionen wählt TS eine geeignete Überlastung korrekt aus. Wenn Sie also error TS2352: Neither type 'Timer' nor type 'number' is assignable to the other stellen Sie sicher, dass Sie eine Zeitüberschreitung angeben!

Hallo @Penryn, danke für das Heads Up!

Ich denke, mein vorheriger Kommentar ist ein Beweis dafür, dass ich nicht genug Details angegeben habe, da ich mich nicht mehr an die genauen Details zu dieser Fehlermeldung erinnern kann. Es tut uns leid.

Das Problem, das wir zuvor hatten, war, dass wir inkrementelle Upgrades unserer in Angular2 (Alpha-Versionen) geschriebenen Spin-off-Web-App durchführen. Unsere Hauptcodebasis (ng1 und ng2) ist in TypeScript (mit Laubkomponenten, einer Reihe anderer Typisierungen und wenigen benutzerdefinierten Typisierungen) geschrieben, und Angular2 war zu dieser Zeit auch Versand-Typisierungen, Knotentypisierungen usw. Mit unseren Knotentypisierungen (veraltet) Version) und ng2-Knotentypisierungen (und möglicherweise andere Typisierungen), der TS-Compiler wird effektiv über Dups-Typisierungen verwirrt. In unserem Fall hätten wir die fehlerhaften Eingaben manuell ändern können, aber es ist einfach zu viel Arbeit zu wissen, dass wir irgendwann die neueste (n) Version (en) herausholen müssen.

Ich denke, dies wurde in den letzten Angular2-Versionen behoben, da wir die erforderlichen Eingaben manuell installieren müssen.

Prost

@ RyanCavanaugh haben das gleiche Problem. Ich sehe, dass ich zwei Definitionen für setTimeout habe. Einer gibt number und der andere gibt NodeJS.Timer .

Verwenden Sie stattdessen einfach window.setTimeout .

Warum erfordert das NodeJS.Timer einen speziellen Typ? Es wird immer noch nur ein number oder? Vermisse ich etwas

@cchamberlain Node gibt tatsächlich eine gesamte Timer-Klasse zurück: https://nodejs.org/api/timers.html

In diesem Fall also nicht nur ein number .

@Penryn - TIL 👍

Für Neugierige ist der Grund dafür, dass setTimeout in node.js etwas anderes zurückgibt als setTimeout im Browser. Das setTimeout des Browsers gibt nur eine Zahl zurück. In node.js gibt setTimeout ein großes Timer-Objekt zurück.

Der Grund, warum Sie dieses Problem sehen, ist mit ziemlicher Sicherheit, dass Sie beabsichtigt haben, auf das Web abzuzielen, aber Knotendefinitionen eingezogen haben.

@johnfn könnte auch isomorpher Code sein, der auf Browser und Knoten

Für andere, die mit setTimeout oder setInterval hierher kommen, verwenden Sie window.setTimeout oder interval damit tsc weiß, dass Sie die Funktion des Webbrowsers verwenden (die die Nummer zurückgibt) ) und nicht die Funktion von NodeJS (die etwas anderes zurückgibt).

Um @AskYous zu window.setInterval , um den Typfehler zu @types/node in den Paketen haben.

Für diejenigen, die @angular mit @angular-cli stellen Sie sicher, dass Sie den Typknoten auch auf Ihrem tsconfig.app.json .

Gl.:

tsconfig.app.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es6",
    "baseUrl": "",
    "types": ["node"] --> ADD THIS
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}

Ich habe es hier gefunden: https://stackoverflow.com/a/43952363/3415716

Vielleicht haben Sie ein Paket importiert, das eine Funktion mit dem Namen setTimeout() .
Verwenden Sie einfach window.setTimeout anstelle von setTimeout , um das Problem zu lösen :)

In der Knotenumgebung ist der Typ NodeJS.Timer Verwenden Sie global.setTimeout
und in der Browserumgebung ist der Typ number use window.setTimeout

heute nach der Installation von npm i @types/react @types/react-dom --save-dev

Das @types\node ist in node_modules @types\node durchgesickert und hat somit den Fehler Timer verursacht

Wie @ nippur72 bin ich heute mit react-dom gestoßen . Ich denke, die einfachste Lösung besteht darin, das @types -Paket so zu aktualisieren, dass es nicht vom Knoten abhängt, wenn eine Browserumgebung erwartet wird. Daher: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/21310#issuecomment -367919251

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen