
TypeScript es un lenguaje de programación fuertemente tipado y uno de los objetivos del sistema de tipos es hacer explícito la intención de código, con la finalidad de crear un código más robusto y consistente, pero si no usamos el sistemas de tipos adecuadamente podemos volver a caer el mismo infierno de JavaScript, siendo el tipo any uno de los más peligrosos si se usa sin una razón válida.
A una variable de tipo any se le puede asignar cualquier cosa, esto elimina las restricción de tipos, veamos algunos casos:
Caso 1
La variable country puede ser de cualquier tipo, string, number, boolean, etc, no es una variable fiable
let country: any = 'Perú'; // string country = 1; // number country = false; // boolean
Si usáramos un tipo definido, como por ejemplo country: string TypeScript nos alertaría con un mensaje, el cual diría algo parecido a esto, «El tipo ‘string’ no se puede asignar al tipo ‘number'». y no transpilaria el código hasta solventar el problema.
Caso 2
Usar any como tipo para los parámetros de una función (en este caso una función de suma), permitiría pasar cualquier cosa como parámetro, y en vez de sumar haría concatenaciones y estaríamos en la misma condición como si lo hicieras con JavaScript, ¡sin ninguna seguridad!
function sum(a: any, b: any) {
return a + b
}
console.log(sum("Hello ", "World")) // "Hello World"
console.log(sum("Hello ",{a:10})) // "Hello Object Object"
Caso 3
Definir un objeto como any nos da la libertad de acceder a cualquier atributo del objeto, ¡así no exista!
const book: any = {
author: "author name",
issn: "issn value"
};
console.log(book.doi) // undefined
Y así podríamos seguir, con muchos más ejemplos, de lo perjudicial que puede ser any , ¿pero qué tipo de datos podemos usar si no sabemos el tipo?, la respuesta es: unknown.
Si no conoce el valor de una variable, objeto, parámetro, etc, en el 99 % de los casos debería usar
unknownen vez deany.
Unknown
Usar unknown nos permite trabajar con valores desconocidos con la seguridad de tipos , las dos principales características de unknown son:
- No permite que una variable definida como
unknownpueda ser asignada a otra, evitando así la propagación de datos inconsistentes.
let x:unknown = 10;
let v1: number = x // Error
let v2: object = x; // Error
let v3: string = x; // Error
let v4: string[] = x; // Error
let v5: {} = x; // Error
let v6: {} | null | undefined = x; // Error
// definimos el tipo
let v10: number = x as number // Ok
2. No permite realizar operaciones con el valor hasta definir un tipo específico.
function sum(a:unknown, b: number) {
// comprobando el tipo
if(typeof a === "number"){
return a + b
}
throw new Error(`La variable '${a}' no es un número`);
}
sum(10,2) // 12
// Error
sum("hola",2) // La variable 'hola' no es un número
sum({a:5},2) // La variable [object Object] no es un número
Si recibimos objetos que no sabemos su tipo, lo definimos como unknown para evitar que sea invocado directamente y haciendo uso de una interface o type podemos delimitar los atributos que queremos usar y si no está definido el atributo en nuestra interface o type TypeScript nos alertará.
// API y no conocemos su tipo
const apiBook: unknown = {
author: "author name",
issn: "issn value"
....
};
interface book {
author: string
issn: string
}
// definimos el tipo book
const x = apiBook as book;
console.log(x.author) // author name
console.log(apiBook.author) // Error, Object is of type 'unknown'.
Cuidarnos de any
TypeScript nos provee dentro del archivo de configuración tsconfig.json una opción donde podemos definir la regla noImplicitAny a true para que TypeScript nos alerte cada vez que se usa un tipo any.
{
"compilerOptions": {
...
"noImplicitAny": true
...
}
}
O si quiere ir un paso más allá, (mi opción preferida y recomendada) es usar strict: true
{
"compilerOptions": {
...
"strict": true
...
}
}
Esto habilitará las siguientes reglas:
noImplicitAnynoImplicitThisstrictNullChecksalwaysStrict
Pero si hay una justificación válida para el uso de any y deseamos usarlo sin desactivar nuestra regla podemos usar // @ts-ignore, para ignorar todas las reglas.
// @ts-ignore
const myApiVar:any = {} // no mostrará ninguna alerta
¿Cuales son los casos en que se puede usar any?
- Cuando hacemos migraciones de JavaScript a TypeScript, podemos marcar las variables como
anypara ir paso a paso y evitar de que se rompa todo. - Cuando estamos usando librerías de terceros y no tenemos un tipo disponible para ese dato, ejemplo la librería nos devuelve un tipo de dato
currencyy ese tipo no podemos importarlo a nuestro proyecto o no podemos reproducirlo.
¿Que otro caso consideras que se justifica usar any?
Muchas gracias, me ha sido muy útil.
Me alegra mucho