Je travaille sur la mise à niveau d'un ancien code TypeScript pour utiliser la dernière version du compilateur, et j'ai des problèmes avec un appel à setTimeout
. Le code s'attend à appeler la setTimeout
fonction du navigateur qui renvoie un nombre:
setTimeout(handler: (...args: any[]) => void, timeout: number): number;
Cependant, le compilateur résout cela à la place de l'implémentation du nœud, qui renvoie un NodeJS.Timer:
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
Ce code ne s'exécute pas dans le nœud, mais les types de nœud sont extraits en tant que dépendance à quelque chose d'autre (je ne sais pas quoi).
Comment puis-je demander au compilateur de choisir la version setTimeout
que je souhaite?
Voici le code en question:
let n: number;
n = setTimeout(function () { /* snip */ }, 500);
Cela produit l'erreur du compilateur:
TS2322: Le type 'Timer' n'est pas attribuable au type 'number'.
la source
types
n'inclut pasnode
maissetTimeout
obtient toujours son type de nœud plutôt que son type de navigateur.types
par défaut à tous les types denode_modules/@types
, comme expliqué dans typescriptlang.org/tsconfig#types , mais même si vous ne spécifieztypes
et ne pas inclure"node"
, pourquoisetTimeout
n'obtenez toujours son type de nœud et comment pouvez - vous obtenir le type de navigateur? La solution de @ Axke est un peu un hack, disant essentiellement qu'elle renvoie ce qu'elle renvoie. TypeScript peut encore trouver le mauvais type, mais au moins il sera toujours faux.Réponses:
Une autre solution de contournement qui n'affecte pas la déclaration de variable:
De plus, il devrait être possible d'utiliser l'
window
objet explicitement sansany
:la source
window.setTimeout
) devrait être la bonne réponse à cette question car c'est la solution la plus claire.any
type, vous ne donnez pas vraiment de réponse TypeScript.number
type entraînera des erreurs de charpie spécifiques à TypeScript, car lasetTimeout
fonction en nécessite plus.window.setTimeout
peut causer des problèmes avec les frameworks de tests unitaires (node.js). La meilleure solution est d'utiliserlet n: NodeJS.Timeout
etn = setTimeout
.En utilisant,
ReturnType<fn>
vous obtenez l'indépendance de la plate-forme. Vous ne serez pas obligé d'utiliserany
niwindow.setTimeout
qui ne cassera si vous exécutez le code no nodeJS server (par exemple, page de rendu côté serveur).Bonne nouvelle, c'est aussi compatible avec Deno!
la source
setTimeout
/clearTimeout
et n'utilisant pasany
.NodeJS.Timeout
si vous utilisezsetTimeout
directement etnumber
si vous utilisezwindow.setTimeout
. Ne devrait pas avoir besoin d'utiliserReturnType
.setTimeout
fonction et attendez que son résultat soit stocké dans la variable. Essayez-le vous-même dans TS Playground.setTimeout
faux (pour des raisons que personne ne peut expliquer) mais au moins cette solution devrait masquer cela d'une manière légèrement meilleure que la simple utilisationany
.Je suppose que cela dépend de l'endroit où vous exécuterez votre code.
Si votre cible d'exécution est Node JS côté serveur, utilisez:
Si votre cible d'exécution est un navigateur, utilisez:
la source
Cela fonctionnera probablement avec les versions plus anciennes, mais avec la version TypeScript
^3.5.3
et la version Node.js^10.15.3
, vous devriez être en mesure d'importer les fonctions spécifiques au nœud depuis le module Timers , c'est-à-dire:Cela renverra une instance de Timeout de type
NodeJS.Timeout
que vous pouvez passer àclearTimeout
:la source
setTimeout
, quelque chose commeconst { setTimeout } = window
effacera ces erreurs.J'ai été confronté au même problème et la solution de contournement que notre équipe a décidé d'utiliser était simplement d'utiliser "any" pour le type de minuterie. Par exemple:
Il fonctionnera avec les deux implémentations des méthodes setTimeout / setInterval / clearTimeout / clearInterval.
la source
window.setTimeout
peut ne pas fonctionner avec les frameworks de tests unitaires. Il existe un type qui peut être utilisé ici .. SonNodeJS.Timeout
. Vous pensez peut-être que vous n'êtes pas dans un environnement de nœuds mais j'ai des nouvelles pour vous: Webpack / TypeScript etc. exécutent node.js.Si vous voulez une vraie solution pour dactylographié sur les minuteries, nous y allons:
Le bogue est dans le type de retour «nombre» ce n'est pas Timer ou autre chose.
Ceci est pour la solution dactylographié ~> 2.7:
Maintenant, nous avons tout corrigé, déclarez simplement comme ceci:
la source