Estoy trabajando para actualizar un código TypeScript antiguo para usar la última versión del compilador y tengo problemas con una llamada a setTimeout
. El código espera llamar a la setTimeout
función del navegador que devuelve un número:
setTimeout(handler: (...args: any[]) => void, timeout: number): number;
Sin embargo, el compilador está resolviendo esto en la implementación del nodo, que devuelve un NodeJS.Timer:
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
Este código no se ejecuta en el nodo, pero los tipos de nodos se incorporan como una dependencia de otra cosa (no estoy seguro de qué).
¿Cómo puedo indicarle al compilador que elija la versión setTimeout
que quiero?
Aquí está el código en cuestión:
let n: number;
n = setTimeout(function () { /* snip */ }, 500);
Esto produce el error del compilador:
TS2322: El tipo 'Temporizador' no se puede asignar al tipo 'número'.
fuente
types
no incluyenode
perosetTimeout
aún obtiene su tipo de nodo en lugar de su tipo de navegador.types
por defecto a todos los tipos denode_modules/@types
, como se explica en typescriptlang.org/tsconfig#types , pero incluso si lo hace especificartypes
y no incluye"node"
, ¿por quésetTimeout
aún así obtener su tipo de nodo y cómo se puede obtener el tipo de navegador? La solución de @ Axke es un truco, básicamente dice que devuelve lo que devuelve. Es posible que TypeScript siga encontrando el tipo incorrecto, pero al menos siempre será incorrecto.Respuestas:
Otra solución alternativa que no afecta la declaración de variables:
Además, debería ser posible utilizar el
window
objeto explícitamente sinany
:fuente
window.setTimeout
) debería ser la respuesta correcta para esta pregunta, ya que es la solución más clara.any
tipo, realmente no está dando una respuesta de TypeScript.number
tipo dará lugar a errores de pelusa específicos de TypeScript, ya que lasetTimeout
función requiere más que eso.window.setTimeout
puede causar problemas con los marcos de prueba unitarios (node.js). La mejor solución es usarlet n: NodeJS.Timeout
yn = setTimeout
.Al usarlo
ReturnType<fn>
, obtiene independencia de la plataforma. No se verá obligado a usarany
niwindow.setTimeout
que se romperá si ejecuta el código sin servidor nodeJS (por ejemplo, página renderizada del lado del servidor).Buenas noticias, ¡esto también es compatible con Deno!
fuente
setTimeout
/clearTimeout
y no utilizaany
.NodeJS.Timeout
si se usasetTimeout
directamente ynumber
si se usawindow.setTimeout
. No debería necesitar usarloReturnType
.setTimeout
función y espera que su resultado se almacene en la variable. Pruébelo usted mismo en TS playground.setTimeout
error (por razones que nadie puede explicar) pero al menos esta solución debería enmascarar eso de una manera un poco mejor que simplemente usarany
.Supongo que depende de dónde ejecutará su código.
Si su destino de tiempo de ejecución es el nodo JS del lado del servidor, use:
Si su objetivo de tiempo de ejecución es un navegador, use:
fuente
Es probable que esto funcione con versiones anteriores, pero con la versión TypeScript
^3.5.3
y la versión Node.js^10.15.3
, debería poder importar las funciones específicas de Node desde el módulo Timers , es decir:Eso devolverá una instancia de Timeout de tipo
NodeJS.Timeout
que puede pasar aclearTimeout
:fuente
setTimeout
, algo comoconst { setTimeout } = window
aclarará esos errores.Enfrenté el mismo problema y la solución alternativa que nuestro equipo decidió usar fue simplemente usar "cualquiera" para el tipo de temporizador. P.ej:
Funcionará con ambas implementaciones de los métodos setTimeout / setInterval / clearTimeout / clearInterval.
fuente
window.setTimeout
puede no funcionar con marcos de prueba unitarios. Hay un tipo que se puede utilizar aquí .. SuNodeJS.Timeout
. Puede pensar que no está en un entorno de nodo, pero tengo noticias para usted: Webpack / TypeScript, etc.están ejecutando node.js.Si desea una solución real para mecanografiar sobre temporizadores, aquí vamos:
El error está en el tipo de retorno 'número', no es Timer ni nada más.
Esto es para la solución mecanografiada versión ~> 2.7:
Ahora arreglamos todo, solo declaramos así:
fuente