Protecciones de tipos de TypeScript
Los protectores de tipo son una característica poderosa de TypeScript que permite a los desarrolladores realizar verificaciones en tiempo de ejecución para limitar el tipo de una variable. Esto garantiza información de tipo más precisa, lo que genera un código más seguro y predecible. Este artículo explora qué son los protectores de tipo y cómo usarlos de manera efectiva.
¿Qué son los protectores de tipo?
Los protectores de tipo son expresiones que realizan comprobaciones en tiempo de ejecución y permiten que TypeScript infiera un tipo más específico para una variable. Ayudan a discriminar entre diferentes tipos, especialmente cuando se trata de tipos de unión. Los protectores de tipo se pueden implementar utilizando varias técnicas, entre ellas:
- Predicados de tipo definidos por el usuario
- Afirmaciones de tipo
- Comprobaciones de instancias
- Uso del operador
typeof
- Uso del operador
in
Predicados de tipo definidos por el usuario
Los predicados de tipo definidos por el usuario son funciones que devuelven un valor booleano y tienen un tipo de retorno especial que indica el tipo de la variable que se está verificando. A continuación, se explica cómo crearlos y utilizarlos:
function isString(value: any): value is string {
return typeof value === 'string';
}
function printString(value: any) {
if (isString(value)) {
console.log(value.toUpperCase()); // TypeScript knows value is a string here
} else {
console.log('Not a string');
}
}
En el ejemplo anterior, isString
es un predicado de tipo definido por el usuario que ayuda a TypeScript a comprender que value
es una cadena dentro del bloque if
.
Afirmaciones de tipo
Las afirmaciones de tipo le indican a TypeScript que trate una variable como un tipo determinado. Este método no realiza una comprobación en tiempo de ejecución, sino que informa al compilador de TypeScript sobre el tipo. Por ejemplo:
function printLength(value: any) {
console.log((value as string).length); // Assert value is a string
}
En este ejemplo, value as string
le indica a TypeScript que asuma que value
es una cadena sin realizar una verificación en tiempo de ejecución.
Comprobaciones de instancias
Las comprobaciones de instancia se utilizan para determinar si un objeto es una instancia de una clase en particular. Esto resulta útil para limitar los tipos cuando se trabaja con clases:
class Dog {
bark() { console.log('Woof'); }
}
class Cat {
meow() { console.log('Meow'); }
}
function speak(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark(); // TypeScript knows animal is a Dog here
} else {
animal.meow(); // TypeScript knows animal is a Cat here
}
}
En este ejemplo, el operador instanceof
ayuda a TypeScript a inferir el tipo de animal
en función de su clase.
Uso del operador typeof
El operador typeof
se puede utilizar para comprobar tipos primitivos como string
, number
y boolean
:
function processValue(value: string | number) {
if (typeof value === 'string') {
console.log(value.toUpperCase()); // TypeScript knows value is a string here
} else {
console.log(value.toFixed(2)); // TypeScript knows value is a number here
}
}
Aquí, typeof
se utiliza para verificar si value
es una string
o un number
y limita el tipo en consecuencia.
Uso del operador in
El operador in
comprueba la presencia de una propiedad en un objeto. Esto resulta útil para distinguir entre tipos que comparten propiedades comunes:
interface Bird {
fly: () => void;
}
interface Fish {
swim: () => void;
}
function move(creature: Bird | Fish) {
if ('fly' in creature) {
creature.fly(); // TypeScript knows creature is a Bird here
} else {
creature.swim(); // TypeScript knows creature is a Fish here
}
}
En este ejemplo, el operador in
ayuda a TypeScript a determinar si creature
es un Bird
o un Fish
según la presencia de un método.
Conclusión
Los protectores de tipos de TypeScript son herramientas esenciales para trabajar con tipos de forma flexible y segura. Permiten una comprobación de tipos más precisa y pueden evitar errores de ejecución al garantizar que se utilice el tipo correcto en diferentes situaciones. Comprender y utilizar los protectores de tipos de forma eficaz puede dar lugar a un código TypeScript más sólido y fácil de mantener.