Checker, emisión y runtime en TypeScript | Nicolás Garzón
Texto
Copiar archivo .ts
↓ parsear
estructura del programa
↓ enlazar nombres
símbolos y scopes
↓ comprobar tipos
diagnósticos
↓ emitir, si corresponde
JavaScript + declarations + source mapsEl parser comprueba que la sintaxis pueda convertirse en una estructura válida.
TypeScript
Copiar const value = ; Este código no puede analizarse correctamente y produce un error de sintaxis antes de discutir tipos.
TypeScript
Copiar const price = 100 ;
console . log ( prcie) ; El compilador necesita relacionar cada identificador con su declaración. prcie no existe dentro de los scopes visibles.
TypeScript
Copiar const price = 100 ;
price. toUpperCase ( ) ; La sintaxis es válida, pero la operación no pertenece al tipo inferido.
TypeScript
Copiar const price: number = 100 ; JavaScript
Copiar const price = 100 ; Bash
Copiar npx tsc --noEmit Es común en proyectos donde Vite, Next.js, esbuild, SWC u otra herramienta transforma el código.
Texto
Copiar tsc → comprobar tipos
bundler/framework → transformar, empaquetar y servirEvita asumir que tsc siempre es quien construye el JavaScript final.
Bash
Copiar npx tsc -p tsconfig.json --noEmit -p indica qué proyecto comprobar. Ejecutar tsc con archivos sueltos puede utilizar reglas distintas o ignorar la configuración, según la versión y el comando empleado.
Para un repositorio real, comprueba el proyecto, no un archivo aislado con defaults accidentales.
Según la configuración, TypeScript puede emitir JavaScript aunque existan errores.
JSON
Copiar {
"compilerOptions" : {
"noEmitOnError" : true
}
} En un proyecto con bundler y noEmit, la build debe ejecutar el typecheck como paso obligatorio; de lo contrario, otra herramienta puede generar output aunque tsc nunca haya comprobado el código.
Estas construcciones normalmente no existen en runtime:
TypeScript
Copiar interface Product {
id: string ;
}
type ProductId = string ;
function findProduct ( id: ProductId) : Product | null {
return null ;
} El runtime recibe funciones y valores de JavaScript, no interface ni type.
Algunas características de TypeScript sí generan o modifican JavaScript:
TypeScript
Copiar enum Status {
Active,
Disabled,
} También pueden emitir código:
Namespaces.
Parameter properties.
Decorators según el modo.
Downlevel transformations para un target anterior.
No todas las construcciones de TypeScript son comentarios borrables.
JSON
Copiar {
"compilerOptions" : {
"target" : "ES2022"
}
} target comunica qué versión aproximada de sintaxis JavaScript puede recibir el entorno final.
TypeScript puede transformar algunas características:
TypeScript
Copiar const name = user?. profile?. name; pero no añade automáticamente APIs ausentes como fetch, structuredClone o Promise.
JSON
Copiar {
"compilerOptions" : {
"lib" : [ "ES2022" , "DOM" ]
}
} lib controla qué declaraciones globales conoce el checker.
Añadir DOM hace que TypeScript conozca window y document; no crea un navegador dentro de Node.js.
Texto
Copiar tipo disponible ≠ API disponible en runtimeTypeScript
Copiar const product = value as Product; as afecta al checker. No inserta una validación ni cambia el objeto.
TypeScript
Copiar input. value! . trim ( ) ; El ! también desaparece. Si value es realmente null o undefined, JavaScript falla normalmente.
TypeScript
Copiar declare const configuration: Configuration; Promete que el valor existirá en runtime, pero no lo crea.
Texto
Copiar TypeScript: sin error
JavaScript: ReferenceErrorUna librería puede producir archivos .d.ts:
JSON
Copiar {
"compilerOptions" : {
"declaration" : true
}
} Los declarations describen la API pública para otros proyectos, pero no contienen la implementación ejecutable.
JSON
Copiar {
"compilerOptions" : {
"sourceMap" : true
}
} Relacionan el JavaScript emitido con el TypeScript original para debugging. La herramienta que finalmente transforma el código también debe conservar correctamente esa cadena.
Texto
Copiar npx tsc --noEmit
vite buildTexto
Copiar npx tsc -p tsconfig.build.json
→ JavaScript
→ .d.ts
→ source mapsLa configuración depende del producto que estás entregando.
Pensar que todo error de TypeScript impide emitir.
Ejecutar un archivo suelto y creer que utiliza el tsconfig.
Confundir target con disponibilidad de APIs.
Añadir DOM a lib dentro de Node y esperar que exista window.
Creer que as o ! validan.
Utilizar declare para crear valores.
Duplicar transformación entre tsc y bundler sin una razón.
Publicar una librería sin declarations cuando su API debe consumirse con tipos.
Parseo, enlace, checking y emisión son etapas diferentes.
tsc --noEmit comprueba sin producir JavaScript.
La mayoría de tipos desaparecen.
Algunas construcciones de TypeScript sí emiten código.
target controla transformación de sintaxis.
lib controla declaraciones conocidas, no capacidades reales.
Assertions y declare son promesas al checker.
Una build debe integrar typecheck de forma explícita.
¿Por qué añadir "DOM" a lib no permite utilizar document dentro de un proceso Node.js?
Respuesta Porque lib solo añade las declaraciones que usa el checker. El runtime continúa siendo Node.js y no crea las APIs de una ventana del navegador.
Proyecto TypeScript y tsconfig.json convierte estas decisiones en una configuración explícita.