Back

Como Executar TypeScript Nativamente no Node.js

Como Executar TypeScript Nativamente no Node.js

O Node.js 23.6.0 marca um ponto de virada para desenvolvedores TypeScript: agora você pode executar arquivos .ts diretamente sem ferramentas de transpilação como ts-node ou tsc. Este suporte nativo ao TypeScript simplifica os fluxos de trabalho de desenvolvimento ao eliminar etapas de build, mantendo a segurança de tipos através do seu IDE.

Este guia cobre tudo que você precisa para executar TypeScript nativamente no Node.js, desde a configuração básica até considerações de produção. Você aprenderá como funciona a remoção de tipos, quais recursos do TypeScript são suportados e como configurar seus projetos para compatibilidade otimizada.

Principais Pontos

  • O Node.js 23.6.0 executa arquivos TypeScript diretamente sem transpilação
  • A remoção de tipos remove anotações preservando a estrutura do código
  • A maioria dos recursos comuns do TypeScript funciona, mas enums e namespaces requerem soluções alternativas
  • Declarações de import devem incluir a extensão .ts
  • A execução nativa oferece tempos de inicialização 2-3x mais rápidos comparado às ferramentas tradicionais

Início Rápido: Executando TypeScript no Node.js 23.6.0

Vamos começar com um arquivo TypeScript simples para demonstrar a execução nativa:

// greeting.ts
function greet(name: string): string {
  return `Hello, ${name}!`
}

console.log(greet("TypeScript"))

Com Node.js 23.6.0 ou posterior, execute diretamente:

node greeting.ts

É isso—nenhuma etapa de compilação necessária. O Node.js remove as anotações de tipo e executa o JavaScript restante.

Para verificar sua versão do Node.js:

node --version  # Deve ser v23.6.0 ou superior

Você verá um aviso experimental na primeira execução:

ExperimentalWarning: Type Stripping is an experimental feature and might change at any time

Para suprimir este aviso em desenvolvimento:

node --disable-warning=ExperimentalWarning greeting.ts

Ou defina permanentemente:

export NODE_OPTIONS="--disable-warning=ExperimentalWarning"

Entendendo a Remoção de Tipos no Node.js

A remoção de tipos difere fundamentalmente da transpilação tradicional do TypeScript. Em vez de transformar TypeScript em JavaScript, o Node.js simplesmente remove as anotações de tipo preservando a estrutura original do código.

Veja o que acontece durante a remoção de tipos:

// TypeScript original
function calculate(a: number, b: number): number {
  return a + b
}

// Após remoção de tipos (o que o Node.js executa)
function calculate(a        , b        )         {
  return a + b
}

Note a preservação de espaços em branco—isso mantém números de linha precisos para depuração sem necessidade de source maps.

Benefícios de Performance

A execução nativa do TypeScript oferece melhorias significativas de performance:

  • Sem overhead de transpilação: Execução direta sem etapas intermediárias
  • Tempos de inicialização mais rápidos: ~45ms vs. 120ms com ts-node
  • Uso reduzido de memória: Nenhum transpilador carregado na memória
  • Depuração simplificada: Números de linha originais preservados

Evolução do Suporte ao TypeScript no Node.js

Entender a progressão ajuda você a escolher a abordagem correta:

v22.6.0: Remoção Inicial de Tipos

node --experimental-strip-types app.ts

Apenas remoção básica de tipos—sem suporte à sintaxe específica do TypeScript.

v22.7.0: Transformação de Tipos

node --experimental-transform-types app.ts

Adicionou suporte para enums e namespaces através de transformação.

v23.6.0: Remoção de Tipos por Padrão

node app.ts  # Remoção de tipos habilitada por padrão

Nenhuma flag necessária para execução básica de TypeScript.

Recursos TypeScript Suportados e Limitações

O que Funciona

O TypeScript nativo no Node.js suporta a maioria dos recursos cotidianos do TypeScript:

// ✅ Anotações de tipo
let count: number = 0

// ✅ Interfaces
interface User {
  id: number
  name: string
}

// ✅ Aliases de tipo
type Status = 'active' | 'inactive'

// ✅ Genéricos
function identity<T>(value: T): T {
  return value
}

// ✅ Importações de tipo
import type { Config } from './types.ts'

O que Não Funciona

Alguns recursos específicos do TypeScript requerem soluções alternativas:

RecursoSuportadoSolução Alternativa
EnumsUse union types ou objetos const
NamespacesUse módulos ES
Propriedades de parâmetroDeclarações explícitas de propriedades
JSX/TSXUse transpilação tradicional
DecoratorsAguarde suporte do V8

Exemplos de soluções alternativas:

// ❌ Enum (não suportado)
enum Status {
  Active,
  Inactive
}

// ✅ Alternativa com union type
type Status = 'active' | 'inactive'

// ✅ Alternativa com objeto const
const Status = {
  Active: 'active',
  Inactive: 'inactive'
} as const

Extensões de Arquivo e Sistemas de Módulos

O Node.js usa extensões de arquivo para determinar o tratamento de módulos:

  • .ts - Segue o campo "type" do package.json (ESM ou CommonJS)
  • .mts - Sempre tratado como ESM
  • .cts - Sempre tratado como CommonJS

Importante: Importações locais devem incluir a extensão .ts:

// ❌ TypeScript tradicional
import { utils } from './utils'

// ✅ TypeScript nativo do Node.js
import { utils } from './utils.ts'

Configurando tsconfig.json para TypeScript Nativo

Embora o Node.js não leia tsconfig.json durante a execução, a configuração adequada garante suporte do IDE e verificação de tipos:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "allowImportingTsExtensions": true,
    "rewriteRelativeImportExtensions": false,
    "verbatimModuleSyntax": true,
    "strict": true,
    "noEmit": true
  }
}

Configurações principais explicadas:

  • allowImportingTsExtensions: Permite .ts em caminhos de import
  • rewriteRelativeImportExtensions: Definido como false para preservar extensões .ts
  • verbatimModuleSyntax: Força importações explícitas de tipo
  • noEmit: Previne geração acidental de JavaScript

Execute verificação de tipos separadamente:

tsc --noEmit

Guia de Migração de Ferramentas TypeScript Tradicionais

Migrando do ts-node

  1. Remova a dependência do ts-node:
npm uninstall ts-node
  1. Atualize os scripts do package.json:
// Antes
"scripts": {
  "dev": "ts-node src/index.ts"
}

// Depois
"scripts": {
  "dev": "node src/index.ts"
}
  1. Trate recursos não suportados (converta enums para unions)

Migrando da Compilação tsc

  1. Remova etapas de build:
// Remova estes scripts
"scripts": {
  "build": "tsc",
  "start": "node dist/index.js"
}

// Use isto em vez disso
"scripts": {
  "start": "node src/index.ts"
}
  1. Atualize pipelines de CI/CD para pular compilação

Comparação de Performance

A execução nativa do TypeScript mostra melhorias significativas:

MétricaTypeScript Nativots-nodetsc + node
Tempo de inicialização~45ms~120ms~200ms
Uso de memóriaBaseline+30MB+10MB
Etapa de buildNenhumaNenhumaNecessária

Armadilhas Comuns e Soluções

Erros de Caminho de Import

// Erro: Cannot find module './utils'
import { helper } from './utils'

// Solução: Inclua extensão .ts
import { helper } from './utils.ts'

Sintaxe Não Suportada

// Erro: Enums are not supported
enum Color { Red, Blue }

// Solução: Use objeto const
const Color = { Red: 0, Blue: 1 } as const

Confusão na Verificação de Tipos

Lembre-se: O Node.js não realiza verificação de tipos. Sempre execute tsc --noEmit para validação de tipos.

Considerações de Produção

Quando Usar TypeScript Nativo

  • Ambientes de desenvolvimento
  • Protótipos e experimentos
  • Scripts pequenos e utilitários
  • Equipes prontas para recursos experimentais

Quando Evitar

  • Aplicações de produção (até estabilizar)
  • Projetos que requerem recursos completos do TypeScript
  • Equipes que precisam de ferramentas estáveis
  • Pipelines de build complexos

Ajustes no Docker

# Antes
FROM node:23-alpine
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]

# Depois
FROM node:23-alpine
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "src/index.ts"]

Conclusão

O suporte nativo ao TypeScript no Node.js 23.6.0 representa uma simplificação significativa para fluxos de trabalho de desenvolvimento. Ao eliminar etapas de transpilação, você pode focar em escrever código em vez de configurar ferramentas de build. Embora existam limitações—particularmente em torno da sintaxe específica do TypeScript—os benefícios para a maioria dos cenários de desenvolvimento são convincentes.

Comece experimentando TypeScript nativo em seu ambiente de desenvolvimento, migre gradualmente projetos existentes e prepare-se para um futuro onde TypeScript executa em qualquer lugar que JavaScript executa. À medida que este recurso se estabiliza, espere adoção mais ampla e capacidades expandidas nas próximas versões do Node.js.

Perguntas Frequentes

Embora seja tecnicamente possível, ainda não é recomendado para uso em produção. O recurso ainda é experimental e pode mudar. Use-o para ambientes de desenvolvimento, protótipos e aplicações não críticas. Para produção, continue usando transpilação tradicional até que o recurso se torne estável.

Sim, você deve manter o TypeScript como dependência de desenvolvimento para verificação de tipos. O Node.js apenas remove tipos sem validá-los. Execute tsc --noEmit separadamente para capturar erros de tipo durante o desenvolvimento ou em seu pipeline de CI.

O TypeScript nativo requer extensões .ts explícitas em caminhos de import, diferente das ferramentas tradicionais do TypeScript. Atualize todas as importações locais de './module' para './module.ts'. Importações de pacotes externos não precisam de extensões.

Substitua enums por union types para casos simples ou objetos const com asserção as const para enums numéricos. Para string enums, union types funcionam perfeitamente. Esta abordagem é na verdade mais tree-shakeable e se alinha melhor com práticas modernas do TypeScript.

A equipe do Node.js foca na remoção de tipos em vez de transpilação completa por razões de performance. Recursos que requerem transformação em tempo de execução como enums e decorators podem obter suporte quando o V8 os implementar nativamente, mas o objetivo é processamento rápido e mínimo em vez de compatibilidade completa com TypeScript.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay