Estou trabalhando na atualização de algum código TypeScript antigo para usar a versão mais recente do compilador e estou tendo problemas com uma chamada para setTimeout
. O código espera chamar a setTimeout
função do navegador que retorna um número:
setTimeout(handler: (...args: any[]) => void, timeout: number): number;
No entanto, o compilador está resolvendo isso para a implementação do nó, que retorna um NodeJS.Timer:
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
Este código não é executado no nó, mas as tipificações do nó estão sendo puxadas como uma dependência de outra coisa (não tenho certeza do que).
Como posso instruir o compilador a escolher a versão setTimeout
que desejo?
Aqui está o código em questão:
let n: number;
n = setTimeout(function () { /* snip */ }, 500);
Isso produz o erro do compilador:
TS2322: O tipo 'Timer' não pode ser atribuído ao tipo 'número'.
fonte
Respostas:
Outra solução alternativa que não afeta a declaração da variável:
Além disso, deve ser possível usar o
window
objeto explicitamente semany
:fonte
window.setTimeout
) deve ser a resposta correta para essa pergunta, pois é a solução mais clara.any
tipo, não está realmente dando uma resposta TypeScript.number
tipo levará a erros de lint específicos do TypeScript, pois asetTimeout
função requer mais do que isso.window.setTimeout
pode causar problemas com estruturas de teste de unidade (node.js). A melhor solução é usarlet n: NodeJS.Timeout
en = setTimeout
.Ao usar,
ReturnType<fn>
você obtém independência da plataforma. Você não será forçado a usarany
nem owindow.setTimeout
que irá quebrar se você executar o código no servidor nodeJS (por exemplo, página renderizada do lado do servidor).Boas notícias, isso também é compatível com Deno!
fonte
setTimeout
/clearTimeout
e não usaany
.NodeJS.Timeout
se estiver usandosetTimeout
diretamente enumber
se estiver usandowindow.setTimeout
. Não deve ser necessário usarReturnType
.setTimeout
função e espera que seu resultado seja armazenado na variável. Experimente você mesmo no playground do TS.Acho que depende de onde você executará seu código.
Se o destino do tempo de execução for Nó JS do servidor, use:
Se o seu destino de tempo de execução for um navegador, use:
fonte
Enfrentei o mesmo problema e a solução alternativa que nossa equipe decidiu usar foi apenas usar "qualquer" para o tipo de cronômetro. Por exemplo:
Ele funcionará com ambas as implementações dos métodos setTimeout / setInterval / clearTimeout / clearInterval.
fonte
window.setTimeout
pode não funcionar com estruturas de teste de unidade. Existe um tipo que pode ser usado aqui .. SeuNodeJS.Timeout
. Você pode pensar que não está em um ambiente de nó, mas tenho novidades para você: Webpack / TypeScript etc. estão executando node.js.Isso provavelmente funcionará com versões mais antigas, mas com a versão TypeScript
^3.5.3
e a versão Node.js^10.15.3
, você deve ser capaz de importar as funções específicas do Node do módulo Timers , ou seja:Isso retornará uma instância de Timeout do tipo
NodeJS.Timeout
que você pode passar paraclearTimeout
:fonte
setTimeout
, algo comoconst { setTimeout } = window
limpará esses erros.Se você quer uma solução real para datilografia sobre timers, vamos lá:
Bug está no tipo de retorno 'número', não é Timer ou qualquer outra coisa.
Isso é para scripts de versão ~> solução 2.7:
Agora que consertamos tudo, basta declarar assim:
fonte