//
Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Configura un proyecto de React impulsado por TypeScript con un tsconfig.json bien configurado, comprende cómo funcionan los archivos .tsx y aprende las anotaciones de tipo central que todo desarrollador de React necesita.
// tsconfig.json (Next.js 15 / React 19 recomendado)
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [{ "name": "next" }],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}// src/components/Greeting.tsx
type GreetingProps = {
name: string;
age?: number;
};
export function Greeting({ name, age }: GreetingProps) {
return (
<div>
<h1>Hola, {name}</h1>
{age !== undefined && <p>Edad: {age}</p>}
</div>
);
}// Uso
<Greeting name="Alice" />
<Greeting name="Bob" age={30} />.tsx son archivos TypeScript que soportan sintaxis JSX. La configuración jsx: "preserve" le indica a TypeScript que deje JSX sin modificar para que el bundler (Next.js, Vite) lo maneje.strict: true habilita una familia de chequeos estrictos (strictNullChecks, strictFunctionTypes, noImplicitAny, etc.) que detectan la mayoría de bugs.moduleResolution: "bundler" coincide con cómo los bundlers modernos resuelven importaciones, soportando campos exports en package.json e importaciones sin extensión.@/* te permiten escribir import { Button } from "@/components/Button" en lugar de rutas relativas frágiles.Configuración de Vite + React:
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"noEmit": true,
"isolatedModules": true,
"skipLibCheck": true
},
"include": ["src"]
}Agregar opciones más estrictas incrementalmente:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true
}
}npm install -D @types/react @types/react-dom. Con React 19, los tipos se distribuyen con react y @types/react podría no ser necesario dependiendo de tu configuración.type para props y formas simples; usa interface cuando necesites declaration merging o extends.unknown sobre any. Si debes usar any, añade un comentario // eslint-disable y un TODO para solucionarlo después."strict": true significa que TypeScript no marcará acceso a null o undefined, derrotando gran parte de su valor.jsx a "react" en lugar de "preserve" o "react-jsx" te fuerza a hacer import React from "react" en cada archivo.skipLibCheck: true se recomienda para velocidad de compilación pero puede ocultar errores de tipo en tus propios archivos .d.ts.any desactiva silenciosamente el chequeo de tipos para todo lo que ese valor toca posteriormente.| Enfoque | Ventajas | Desventajas |
|---|---|---|
strict: true desde el inicio | Detecta la mayoría de bugs temprano | Curva de aprendizaje más pronunciada para principiantes |
Adopción gradual (strict: false) | Migración más fácil desde JS | Se pierde detección de bugs críticos de null/undefined |
Tipos JSDoc (sin archivos .ts) | Cero cambios en pasos de compilación | Verboso, expresividad de tipos limitada |
interface para todos los props | Declaration merging, estilo OOP familiar | No puede expresar uniones o tipos mapeados |
type para todos los props | Uniones, intersecciones, tipos mapeados | Sin declaration merging |
strictNullChecks, noImplicitAny, strictFunctionTypes y otros chequeos como grupo."preserve" deja JSX sin modificar para que el bundler (Next.js, Vite) maneje la transformación."react-jsx" para proyectos Vite + React que usan el automatic JSX runtime."react" solo si necesitas la transformación clásica React.createElement (requiere importar React en cada archivo).type cuando necesites uniones, intersecciones o tipos mapeados.interface cuando necesites declaration merging o extends.type es suficiente y más flexible.exports en package.json e importaciones sin extensión."node" o "node16" para proyectos agrupados.@types/react podría no ser necesario..tsx soportan sintaxis JSX además de TypeScript..ts son para lógica pura de TypeScript sin JSX..tsx para cualquier archivo que retorne o contenga elementos JSX..d.ts, incluyendo tus archivos de declaración personalizados..d.ts de terceros también son ignorados silenciosamente.any desactiva silenciosamente el chequeo de tipos para el valor y todo lo que toca posteriormente.unknown -- te fuerza a estrechar o validar antes de acceder a propiedades.any, añade un comentario explicando por qué y un TODO para solucionarlo después.{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}@/components/Button a ./src/components/Button.../../../components/Button.noUncheckedIndexedAccess añade | undefined al acceso de índice de array y registro, detectando bugs de fuera de límites.exactOptionalPropertyTypes distingue entre una propiedad faltante y una establecida a undefined.strict: true -- deben habilitarse por separado.type GreetingProps = {
name: string;
age?: number; // opcional
};
function Greeting({ name, age = 25 }: GreetingProps) {
return <p>{name} is {age} years old</p>;
}? en el tipo.undefined.Revisado por Chris St. John·Última actualización: 7 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥