Typescript: setTimeout - l'attribution d'un identifiant de délai d'expiration à une variable génère une erreur TS2323: Le type 'Timer' n'est pas attribuable au type 'number'.

Créé le 7 oct. 2014  ·  24Commentaires  ·  Source: microsoft/TypeScript

En utilisant tsc v1.1.0-1, nous obtenons une erreur lors de la compilation:
erreur TS2323: le type «Timer» ne peut pas être attribué au type «nombre».

le code suivant lève l'erreur de compilation:

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

sTimeout est défini comme un nombre (variable privée).

Question

Commentaire le plus utile

Utilisez simplement window.setTimeout place.

Tous les 24 commentaires

Veuillez poster un exemple complet. Les informations fournies jusqu'à présent ne sont pas suffisantes pour reproduire le problème:

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

Il n'y a pas de type intégré appelé Timer donc il est probable que le setTimeout que vous appelez ne soit pas window.setTimeout .

J'aurais dû faire un exemple - était un peu précipité plus tôt. Voici:

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

Lance l'erreur suivante:

Utilisation de tsc v1.1.0-1
/tests/Foo.ts(5,3): erreur TS2323: Le type 'Timer' n'est pas attribuable au type 'number'.

Pour l'instant, je l'ai corrigé en tapant sTimeout sur any.

Cela ne me reproche pas. Que se passe-t-il lorsque vous F12 setTimeout ?

Vous ne savez pas ce que vous entendez par F12? .

"Aller à la définition"

Encore une fois, il n'y a pas de type intégré appelé Timer , donc votre code doit faire référence à un autre type. Veuillez essayer votre exemple dans un fichier par lui-même, ou déterminez d'où provient ce Timer dans votre projet. Je suppose que setTimeout ne fait pas référence à la fonction intégrée, mais plutôt à une autre fonction définie par l'utilisateur qui a une valeur de retour différente.

J'ai essayé l'exemple par lui-même: on dirait qu'il est causé par un composant de ma chaîne d'outils ou d'un autre code - désolé d'avoir pris votre temps. Merci ... Fermé ...

Pour les futurs lecteurs, je suis tombé sur cette erreur à cause des définitions définitivement typées node.js. La solution consiste à utiliser le nom complet du type, qui est NodeJS.Timer non Timer (ce qui est malheureusement ce que le transpilateur Typescript suggère et ne fonctionne pas).

@jdfreder le temps passe

de toute façon j'ai eu le même problème: error TS2352: Neither type 'Timer' nor type 'number' is assignable to the other. même si j'ai la référence implicite définie en haut du fichier /// <reference path="node_modules/typescript/lib/lib.d.ts" /> ne fonctionne toujours pas.

Le principal problème est que l'un de nos packages npm tiers (angular2) a des typages TS + (nœud et autres) inclus dans le package.

@rixrix (et pour tous ceux qui trouvent cela) J'ai eu un problème similaire jusqu'à ce que je réalise que je ne transmettais pas les bons paramètres.

Comparez ceci, qui nécessite le deuxième paramètre ms et renvoie un NodeJS.Timer :

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

... et ceci, ce qui rend le deuxième paramètre timeout optionnel et renvoie un number :

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

Sur la base de ces deux fonctions, TS sélectionne correctement une surcharge appropriée, donc si vous obtenez error TS2352: Neither type 'Timer' nor type 'number' is assignable to the other assurez-vous de spécifier un timeout!

Salut @Penryn merci pour la tête!

Je pense que mon commentaire précédent témoigne de ne pas donner assez de détails car je ne me souviens plus des détails exacts sur ledit message d'erreur. Désolé.

En plus de ma tête, le problème que nous avions auparavant était lorsque nous effectuons des mises à niveau incrémentielles de notre application Web dérivée écrite en Angular2 (versions alpha). Notre base de code principale (ng1 et ng2) est écrite en TypeScript (avec des composants bower, un tas d'autres typages et quelques typages personnalisés), et Angular2 à l'époque expédiait également des typages, des types de nœuds, etc. Avec nos types de nœuds (obsolètes version) et les typages de nœuds ng2 (et éventuellement d'autres typages), effectivement le compilateur TS se confond avec les typages dups. Dans notre cas, nous aurions pu modifier manuellement les typages incriminés, mais c'est juste trop de travail sachant qu'à un moment donné, nous devrons retirer la ou les dernières versions

Je pense que cela a été résolu dans les dernières versions d'Angular2 car nous devrons installer manuellement les typages requis.

à votre santé

@RyanCavanaugh a le même problème. Je regarde, que j'ai deux définitions pour setTimeout. L'un renvoie number et l'autre retourne NodeJS.Timer .

Utilisez simplement window.setTimeout place.

Pourquoi le NodeJS.Timer nécessite-t-il un type spécial? Il va toujours renvoyer un number non? Est-ce que je manque quelque chose?

@cchamberlain Node renvoie en fait une classe Timer entière: https://nodejs.org/api/timers.html

Donc pas seulement un number dans ce cas.

@Penryn - TIL 👍

Pour les curieux, la raison pour laquelle cela se produit est que setTimeout dans node.js renvoie une chose différente de setTimeout dans le navigateur. Le setTimeout du navigateur renvoie simplement un nombre; dans node.js setTimeout renvoie un gros objet Timer.

Donc, la raison pour laquelle vous voyez ce problème est presque certainement parce que vous avez l'intention de cibler le Web, mais que vous avez intégré des définitions de nœuds.

@johnfn pourrait également être un code isomorphe destiné à cibler le navigateur et le nœud.

Pour les autres utilisateurs qui arrivent ici en utilisant setTimeout ou setInterval , utilisez window.setTimeout ou interval pour que tsc sache que vous utilisez la fonction du navigateur Web (qui renvoie nombre ) et non la fonction de NodeJS (qui renvoie autre chose).

Pour ajouter à @AskYous , si vous avez @types/node dans les packages, utilisez window.setInterval pour éviter l'échec du type.

Pour qui utilise @angular avec @angular-cli assurez-vous que vous avez également le nœud de type sur votre tsconfig.app.json .

Eq:

tsconfig.app.json

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

Je l'ai trouvé ici: https://stackoverflow.com/a/43952363/3415716

Vous avez peut-être importé un package qui a une fonction avec le nom setTimeout() .
Utilisez simplement window.setTimeout au lieu de setTimeout pour résoudre le problème :)

dans le type d'environnement de nœud est NodeJS.Timer use global.setTimeout
et dans l'environnement du navigateur, le type est number use window.setTimeout

aujourd'hui après l'installation de npm i @types/react @types/react-dom --save-dev

le @types\node fui dans node_modules et a donc causé l'erreur Timer

Comme @ nippur72 , je suis tombé sur ça aujourd'hui avec react-dom . Je pense que la solution la plus simple est de mettre à jour le package @types pour ne pas dépendre de Node lorsqu'un environnement de navigateur est attendu, d'où: https://github.com/DefinitelyTyped/DefinatelyTyped/issues/21310#issuecomment -367919251

Cette page vous a été utile?
0 / 5 - 0 notes