A diferencia de muchos lenguajes orientados a objetos, TypeScript implementa la tipificación estructural (duck typing): un objeto se considera compatible con un tipo si tiene todas las propiedades necesarias, independientemente de si se declara explícitamente como de ese tipo.
Esta flexibilidad a veces lleva a que se acepten objetos como tipos si la estructura coincide, aunque en realidad no estén relacionados en significado. Esto es peligroso en modelos de datos complejos, cuando la coincidencia de estructuras es accidental.
Siempre estructura correctamente los tipos de objetos, minimiza las coincidencias de estructuras entre diferentes entidades, y para casos críticos usa propiedades o símbolos adicionales para "nominalizar" los tipos.
Ejemplo de código:
interface Point { x: number; y: number; } interface Pixel { x: number; y: number; } function drawPoint(p: Point) { console.log(p.x, p.y); } const pixel: Pixel = { x: 1, y: 2 }; drawPoint(pixel); // OK, los tipos son estructuralmente compatibles
Características clave:
Si la estructura de dos interfaces coincide, ¿significa que son completamente intercambiables?
Puede que sí por estructura, pero no por la lógica del programa. Esto es aceptable a nivel de compilador, pero puede llevar a errores lógicos (por ejemplo, Point y Pixel arriba).
¿Se puede prohibir la compatibilidad estructural para algún tipo?
No completamente, pero se puede añadir una propiedad única (por ejemplo, con un símbolo):
interface Brand { _brand: unique symbol; }
Ahora otro objeto no podrá imitar este tipo sin el mismo símbolo único.
¿En qué se diferencia la tipificación estructural de la nominal?
La estructural se basa en la presencia de una estructura, la nominal en la coincidencia del nombre del tipo en un espacio de nombres determinado. En TS, por defecto, siempre se utiliza la tipificación estructural.
En varias entidades coincidieron accidentalmente los campos (por ejemplo, User y Admin como {id: number, name: string}), lo que llevó a confusiones al trabajar con contratos API.
Pros:
Contras:
Uso de "etiquetas" únicas y campos no estándar para diferenciar tipos semánticamente diferentes con la misma estructura.
Pros:
Contras: