DEV Community

Cover image for Const Assertions en TypeScript 🤔
Cristian Fernando
Cristian Fernando

Posted on

Const Assertions en TypeScript 🤔

Índice

  1. ¿Qué es una aserción de tipo en TypeScript?
  2. ¿Qué es una const assertion en TypeScript?
  3. Casos de uso de const assertions
  4. const assertions en primitivos
  5. const assertions en arreglos
  6. const assertions en objetos
  7. Conclusiones
  8. Referencias

1. ¿Qué es una aserción de tipo en TypeScript?

TypeScript tiene la ventaja de proporcionarnos tipos de datos para nuestras variables lo que mejora enormemente la escritura y mantenibilidad de nuestro código.

No siempre podemos indicar el tipo de dato de una variable, en estos casos podemos usar lo que se denomina una aserción de tipo que consiste en convertir un tipo de dato en otro, como si fuera un cating de tipos. Veamos algunos ejemplos:

const saludo = "Hola mundo" as string;

let nombres = ["Carlos", "Juan", "Pedro"];
nombres as string[] // un arreglo de cadenas
nombres as [string, string, string]; // una tupla de tres cadenas
nombres as ["Carlos", "Juan", "Pedro"] // una tupla literal de 3 nombres específicos 
Enter fullscreen mode Exit fullscreen mode

2. ¿Qué es una const assertion en TypeScript?

Veamos la siguiente función:

function test(text:string){ // regresa (string | number)[]
    return [text[0], text.length]
}

const res = test("Cris");
console.log(res) // ["C", 4]
res.push("Hola");
console.log(res) // ["C", 4, "Hola"]
Enter fullscreen mode Exit fullscreen mode

La función test regresa un arreglo de cadenas o números lo que tiene sentido por que estamos obteniendo el primer carácter de la cadena pasada por parámetro y luego la longitud de dicha cadena.

En este ejemplo podemos agregar mas items al arreglo resultante siempre y cuando sean de tipo cadena o número sin ningún problema.

Ahora refactoricemos la función agregando una const assertion:

function test(text:string){ // regresa readonly [string, number]
    return [text[0], text.length] as const
}

const res = test("Cris");
console.log(res) // ["C", 4]
res.push("Hola");
console.log(res) // Error
Enter fullscreen mode Exit fullscreen mode

Ahora nuestra función regresa una tupla de 2 posiciones, la primera una cadena y la segunda de un número además de ser de solo lectura.

En este ejemplo no podemos agregar mas items al arreglo resultante puesto que esta limitado a solo recibir dos: una cadena y un número en ese orden.

Lo que hace la const assertion con el código as const justamente es convertir el tipo de regreso a su tipo mas literal posible.

3. Casos de uso de const assertions

Existen 3 casos en los que podemos usar una const assertion:

  • Con primitivos: se convierten a sus literales inmediatos.

  • Con arreglos: se convierten en tuplas de solo lectura (como en nuestro ejemplo).

  • Con objetos: las propiedades de los objetos se convierten en solo de lectura.

4. const assertions en primitivos

Con tipos primitivos se convierten en sus literales mas proximos.

const getName = () => { // regresa un string
    return "Anna Bela" 
}

const getName = () => { // regresa "Anna Bela"
    return "Anna Bela" as const
}
Enter fullscreen mode Exit fullscreen mode

Veamos otro ejemplo:

interface User {
    nombre:string;
    edad: number;
    tipo: "admin" | "normal"
}

const f = (user:User) => {
    if(user.tipo === "admin"){
        return user.nombre.toUpperCase();
    }
    return user.edad;
}

const cris = {
    nombre:"Cris",
    edad:25,
    tipo: "admin" // para TypeScript esto es un string y no una cadena literal
}

console.log(f(cris)) // Error, TypeScript no tiene como diferenciar entre un string y una cadena literal
Enter fullscreen mode Exit fullscreen mode

Para arreglar esto debemos usar const as de la siguiente manera:

const cris = {
    nombre:"Cris",
    edad:25,
    tipo: "admin" as const // ahora si TypeScript sabe que "admin" es una cadena literal y no cualquier string
}
Enter fullscreen mode Exit fullscreen mode

5. const assertions en arreglos

Con arreglos convertimos el tipo a un tupla de solo lectura:

let arr = [1,2,3] as const
arr.push(4); // no podemos agregar mas valores a la tupla
console.log(arr)
Enter fullscreen mode Exit fullscreen mode

En este ejemplo el tipo de dato de arr es readonly [1,2,3].

Tampoco podemos modificar sus valores por que es de solo lectura:

let arr = [1,2,3] as const
arr[0] = 20 // Error
Enter fullscreen mode Exit fullscreen mode

6. const assertions en objetos

Con los objetos obtenemos las propiedades de solo lectura, por ejemplo:

type Preferencia = "si" | "no" | "quizas";

const f = (obj:Preferencia) => {
    switch(obj){
        case "si":
            return "Genial";
        case "no":
            return "Que mal";
        case "quizas":
            return "Ups!";
        default:
            return "Opciones incorrectas";
    }
}

const miObj = {
    manzana: "si"
};

console.log(f(miObj.manzana)) // string no se puede asignar al tipo literal de Preferencia

Enter fullscreen mode Exit fullscreen mode

Para arreglar esto debemos usar as const y convertir el primitivo a su tipo literal:

const miObj = {
    manzana: "si" as const
};
Enter fullscreen mode Exit fullscreen mode

7. Conclusiones

*Las const assertions son muy útiles para poder hacer un casting de tipos de datos en nuestros programas de TypeScript.

  • Esta característica solo esta disponible en TypeScript, al compilar el código a JavaScript desaparece esta funcionalidad.

  • Recuerda que lo único que hace as const es convertir variables a sus tipos literales mas proximos y volverlos de solo lectura, eso es todo.

8. Referencias

Learning TypeScript, Josh Goldberg

end

Top comments (0)