O TypeScript não tem um sleep embutido. Escreva uma função que retorna uma Promise<void> que o setTimeout resolve depois do intervalo, e use await nela dentro de uma função async:
await sleep(300) pausa só a main. O programa não fica congelado: timers, outras funções async e I/O continuam rodando enquanto ela espera.
Como a função sleep funciona
setTimeout(resolve, ms) agenda resolve para ser chamado depois de ms milissegundos, e chamar resolve resolve a promise. O await nessa promise suspende a função async até lá.
O argumento de tipo <void> importa. Um new Promise(...) isolado não infere o seu tipo a partir das chamadas de resolve, então sem ele sleep retornaria Promise<unknown>. E é o void que permite chamar resolve sem valor: em uma Promise<number>, resolve() sem argumento é erro de compilação. Quando a função tem um tipo de retorno declarado, o argumento de tipo pode ir ali:
setTimeout garante um mínimo, não um tempo exato: o callback roda quando o intervalo já passou e o event loop está livre. Conte com alguns milissegundos de folga.
Sleep dentro de um loop
await sleep() dentro de um loop for ou for...of faz uma pausa entre as iterações, e é assim que você controla o ritmo do trabalho (limites de taxa, polling, animações no terminal):
Isso não funciona dentro de forEach: ele ignora a promise que cada callback async retorna, então todas as iterações começam ao mesmo tempo e nada espera. Use um loop for ou for...of, como explicado na página de async/await.
Retry com delay
Um uso real comum: tentar uma operação e, se ela falhar, esperar e tentar de novo, dobrando a espera a cada vez (exponential backoff).
O return await fn() dentro do try importa: sem await, uma promise rejeitada seria retornada antes que o catch pudesse vê-la.
Um sleep cancelável
Um sleep simples não pode ser interrompido. Para parar de esperar antes (o usuário clicou em Cancelar, um desligamento começou), passe um AbortSignal e limpe o timer quando ele disparar:
O programa termina logo depois do abort porque o timer longo foi limpo. Sem clearTimeout, o Node continuaria rodando até os 5 segundos passarem.
Os timers com promise embutidos no Node
O Node traz uma versão com promise de setTimeout no módulo node:timers/promises, então em código Node você pode importá-la em vez de escrever o helper. Ela também aceita um valor para resolver e um AbortSignal:
import { setTimeout as sleep } from "node:timers/promises";
async function main() {
await sleep(1000); // wait one second
const result = await sleep(500, "done"); // resolves with "done"
const ac = new AbortController();
await sleep(10_000, undefined, { signal: ac.signal }); // cancellable
}
Os tipos vêm de @types/node (npm i -D @types/node). Esse módulo não existe nos navegadores, onde o helper de uma linha é a escolha portável.
Não existe sleep bloqueante
Linguagens com threads têm um sleep que bloqueia a thread atual. O JavaScript roda o seu código em uma única thread com um event loop, então um sleep bloqueante congelaria todo o resto: nenhum timer dispara, nenhuma resposta de rede é tratada e, no navegador, a página para de responder. Um loop ocupado que gira até o relógio passar de um certo horário faz exatamente isso, e nunca é a ferramenta certa.
O sleep assíncrono é o jeito como a espera funciona em JavaScript e TypeScript: a função é suspensa, a thread fica livre e a função retoma quando o timer dispara. Atomics.wait pode bloquear de verdade, mas só em um SharedArrayBuffer, e os navegadores o proíbem na thread principal; ele existe para coordenar worker threads, não para delays.
Perguntas frequentes
Como fazer um sleep no TypeScript?
Defina const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)); e chame await sleep(1000) dentro de uma função async. Isso pausa essa função por cerca de um segundo sem bloquear o resto do programa.
Existe uma função sleep embutida no TypeScript?
Não. O TypeScript adiciona tipos ao JavaScript e não tem uma biblioteca de tempo de execução própria, e o JavaScript não tem sleep. No Node você pode importar uma: import { setTimeout as sleep } from "node:timers/promises". No navegador, escreva o helper de uma linha.
Por que o sleep precisa de await?
sleep(1000) retorna uma promise na hora; só o await pausa a função async em volta até ela resolver. Sem await, a próxima linha roda imediatamente. await só funciona em uma função async (ou no nível superior de um módulo ES).
Posso bloquear a thread com um sleep síncrono no TypeScript?
Não em código normal. O JavaScript roda em uma thread só com um event loop, e um loop de espera ativa congela tudo: timers, callbacks de rede, a página inteira. Use o sleep assíncrono. Atomics.wait pode bloquear uma thread no Node ou em um worker, mas isso serve para coordenação de workers em baixo nível, não para delays.