Mejores Prácticas de TypeScript: Seguridad de Tipos y Calidad de Código
TypeScript agrega verificación de tipos estática a JavaScript, mejorando la calidad del código y la experiencia del desarrollador. Esta guía cubre las mejores prácticas de TypeScript y técnicas de seguridad de tipos.
Actualizado:¿Por qué usar TypeScript?
TypeScript es un superconjunto de JavaScript. Todo el código JavaScript es código TypeScript válido. Agrega verificación de tipos estática.
Seguridad de tipos: Detecta errores de tipo en tiempo de compilación. Reduce errores en tiempo de ejecución (undefined is not a function).
Experiencia del desarrollador: Las funciones de autocompletado de IDE, refactoring y go-to-definition funcionan con información de tipos.
Proyectos grandes: A medida que crece la base de código, la verificación de tipos facilita el mantenimiento y el refactoring. Mejora la colaboración en equipo.
Mejores Prácticas de Definición de Tipos
interface vs type: Use interface para formas de objetos. Use type para tipos union/intersection. interface puede extenderse con extends.
Evite any: any desactiva la verificación de tipos. Use unknown y realice verificación de tipos: if (typeof x === 'string') { ... }.
Modo strict: Establezca strict: true en tsconfig.json. Esto habilita controles como noImplicitAny, strictNullChecks, strictFunctionTypes.
Inferencia de tipos: Use la inferencia de tipos de TypeScript en lugar de anotación de tipo explícita. const name = 'John' (inferido como string).
Tipos literales: Use valores específicos en lugar de string o number: type Status = 'active' | 'inactive' | 'pending'.
Técnicas Avanzadas de Tipos
Tipos genéricos: Cree funciones y clases reutilizables y seguras en tipos: function identity<T>(arg: T): T { return arg; }.
Tipos condicionales: Retorne diferentes tipos basados en condiciones de tipo: type IsString<T> = T extends string ? true : false.
Tipos mapeados: Transforme tipos existentes: type Readonly<T> = { readonly [P in keyof T]: T[P]; }.
Tipos de utilidad: Use los tipos de utilidad integrados de TypeScript: Partial, Required, Pick, Omit, Record, Exclude, Extract.
Tipos de plantilla literal: Cree strings seguros en tipos con manipulación de strings: type EventName = `on${Capitalize<string>}`.
TypeScript con React
Definición de props: interface Props { name: string; age?: number; onClick: () => void; }. Use ? para props opcionales.
useState: const [count, setCount] = useState<number>(0);. La inferencia de tipos suele ser suficiente: useState(0) (inferido como number).
useRef: const inputRef = useRef<HTMLInputElement>(null);. Use el tipo correcto para referencias de elementos DOM.
Manejadores de eventos: Use tipos de eventos de React como React.ChangeEvent<HTMLInputElement>, React.FormEvent<HTMLFormElement>.
Children: Use React.ReactNode (general) o React.ReactElement (solo elemento). Agregue prop children con PropsWithChildren.
Manejo de Errores y Depuración
Aserciones de tipo: Convierta tipos con la palabra clave as: const value = input as string. Prefiera type guards cuando sea posible.
Type guards: Realice verificación de tipo en tiempo de ejecución con typeof, instanceof, operador in y funciones de type guard personalizadas.
Non-null assertion: Especifique que el valor no es null/undefined con el operador !: element!.value. Use solo cuando esté seguro.
tsconfig strictNullChecks: Maneje null y undefined explícitamente. Use optional chaining (?.) y nullish coalescing (??).
ESLint + TypeScript: Agregue reglas adicionales con el plugin @typescript-eslint. Habilite reglas como no-unused-vars, no-explicit-any.
Configuración del Proyecto
tsconfig.json: Establezca strict: true, target: 'ES2020', module: 'ESNext', moduleResolution: 'bundler', esModuleInterop: true.
Path aliases: Acorte las rutas de importación con baseUrl y paths: "@/*": ["src/*"]. import { Button } from '@/components/Button'.
Project references: Use project references para builds incrementales en proyectos grandes. Use el array references en tsconfig.json.
Monorepo: Configure monorepo de TypeScript con Turborepo o Nx. Cree paquetes compartidos para tipos y utilidades.
Declaration files: Agregue definiciones de tipo a bibliotecas JavaScript con archivos .d.ts. Use paquetes @types/*.