Para describir estructuras de datos complejas en TypeScript se utilizan interfaces (interface) y alias de tipos (type). Se pueden combinar con objetos, arreglos y tipos anidados para una tipificación estricta de colecciones complejas.
Para un objeto anidado:
interface Address { city: string; zip: number; } interface UserProfile { name: string; age: number; address: Address; }
Para un arreglo con diferentes tipos:
// Tupla let tuple: [string, number] = ['John', 30]; // Arreglos con tipos union let arr: (string | number)[] = [1, 'a', 2, 'b']; // Arreglo de objetos let users: UserProfile[] = [ {...}, {...} ];
Cuando las estructuras son complejas y hay campos opcionales, se utiliza ?, se combinan con tipos Partial, Record, Mapped Types, o tipos recursivos para árboles anidados.
Pregunta: ¿Se puede usar una interfaz para describir un arreglo con elementos de diferentes tipos (por ejemplo, [string, number, boolean])?
Respuesta: No. Para este caso es mejor usar tuplas — las interfaces no son adecuadas para posiciones y tipos fijos. Las tuplas permiten establecer estrictamente los tipos por cada posición.
type MyTuple = [string, number, boolean]; let foo: MyTuple = ['ok', 12, false];
Historia
En el proyecto se describió incorrectamente una estructura compleja: para un arreglo de tipos mixtos se utilizó any[] en lugar de una tupla o un tipo union correcto. Como resultado, uno de los elementos tenía un valor de un tipo incorrecto, lo que llevó a un error en la lógica del negocio (operación aritmética con una cadena).
Historia
En la estructura de datos, los objetos profundamente anidados se declararon sin utilizar tipos recursivos o Partial. Intentar agregar un nuevo subárbol a un nodo del árbol causaba un error del compilador, y los desarrolladores eludían esto a través de downcast a any, lo que luego causó errores en tiempo de ejecución en producción.
Historia
El objeto con la descripción del perfil del usuario era parcialmente opcional, pero el desarrollador no utilizó ?. Al obtener datos del servidor, TypeScript no emitió advertencias, y la aplicación falló al intentar acceder a campos que no existían en el objeto.