Bienvenidos sean a este post, hoy veremos otras variantes de type mapeado.
En el post anterior hablamos sobre type mapeado y como ejemplo creamos un tipo que podemos considerar como weak o debil. Pero este tipo ya existe en el lenguaje y se lo conoce como Partial. Se agrego en la libreria lib.es5.d.ts, veamos como se definio en este:
type Partial<T> = {
[P in keyof T]?: T[P];
};
Es igual al que vimos en el post anterior donde tomara todas las claves de las propiedades y los convertira en tipo opcional. A su vez este tipo tiene su contraparte denominada como Required. Esta hace lo contrario a Partial marcando a todas las propiedades como requeridas.
En este post mencionamos que entre los modificadores de acceso teniamos uno llamado readonly, el cual es similar a const dado que una vez aplicado el valor no puede ser modificado, y este a su vez posee un tipo de este estilo. Veamos como es su definicion en la libreria:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
Este es tambien un type mapeado pero en las propiedades le aplicara el modificador readonly, como haciamos con el opcional en Partial, y dejandolas de esta forma. Para entenderlo mejor vamos a analizar el siguiente codigo:
interface IRequerido {
id: number;
nombre: string;
}
let soloLectura: Readonly<IRequerido> = { id: 1, nombre: "tinchicus" }
soloLectura.id = 2;
Esta es una interfaz con dos propiedades, lo siguiente es crear un objeto donde usaremos a Readonly y como tipo generico pasaremos la interfaz anterior. Luego le estableceremos los valores a las propiedades. Para finalmente modificar el valor id del objeto anterior. Compilemos y veamos su salida:
$ tsc
tipos.ts:8:13 - error TS2540: Cannot assign to 'id' because it is a read-only property.
8 soloLectura.id = 2;
~~
Found 1 error in tipos.ts:8
$
Como comentamos anteriormente al ser todas las propiedades de solo-lectura podemos solamente consultar los valores y no modificarlos.
Ya vimos dos type mapeados, como son Partial y Readonly, pero disponemos de un par mas como son Pick y Record. El tipo Pick es usado para construir un tipo basado en un subconjunto de propiedades de otro tipo. Analicemos el siguiente ejemplo:
interface IRequerido {
id: number;
nombre: string;
desc: string,
}
type elegir = Pick<IRequerido, "id" | "desc">;
let elegirObjeto: elegir = {
id: 1,
nombre: "tinchicus"
}
Tomamos la interrfaz anterior y le agregamos una nueva propiedad. Luego definimos un type y usaremos a Pick. En este caso como tipo le pasamos la interfaz anterior y lo siguiente seran las propiedades que «elegiremos» para ser utilizadas. Luego crearemos un objeto del type anterior y pasaremos estas dos propiedades. Compilemos y veamos como es su salida::
$ tsc
tipos.ts:10:2 - error TS2353: Object literal may only specify known properties, and 'nombre' does not exist in type 'elegir'.
10 nombre: "tinchicus"
~~~~~~
Found 1 error in tipos.ts:10
$
Como pasamos una propiedad que no «elegimos», este nos impide compilarlo. Es decir, como comentamos anteriormente solo podran usar las propiedades seleccionadas, tomemos el codigo anterior y realicemos la siguiente modificacion:
interface IRequerido {
id: number;
nombre: string;
desc: string,
}
type elegir = Pick<IRequerido, "id" | "desc">;
let elegirObjeto: elegir = {
id: 1,
desc: "es de prueba"
}
Si lo comparan con el anterior, la unica modificacion es la utilizacion de la propiedad desc en lugar de nombre. Si lo compilan de nuevo ahora no tendran ningun error porque utilizamos las propiedades elegidas.
Solo nos resta un tipo, en este caso es Record y lo podemos considerar el opuesto a Pick porque este lo hara en la ejecucion u On Fly. Analicemos el siguiente ejemplo:
type Registrado = Record< "a" | "b", number>;
let registrado: Registrado {
a: 1,
c: 1
};
Primero definiremos el type, y para este usaremos a Record donde primero pasaremos las propiedades que buscara y luego el tipo de dato, en este caso usaremos a number para facilitarlo. Luego crearemos un objeto del tipo de la interfaz anterior donde pasaremos dos propiedades de tipo number pero una tendra otro nombre, Compilemos y veamos que sucede:
$ tsc
tipos.ts:4:2 - error TS2353: Object literal may only specify known properties, and 'c' does not exist in type 'Registrado'.
4 c: 1
~
Found 1 error in tipos.ts:4
$
Como c no existe nos indica que no podemos utilizarlo, tomemos el codigo anterior y realicemos la siguiente modificacion:
type Registrado = Record< "a" | "b", number>;
let registrado: Registrado = {
a: 1,
b: "tinchicus"
};
En este caso modificamos la segunda propiedad donde le establecemos el nombre que corresponde pero le pasamos un valor de tipo string. Compilemos y veamos que sucede:
$ tsc
tipos.ts:4:2 - error TS2322: Type 'string' is not assignable to type 'number'.
4 b: "tinchicus"
~
Found 1 error in tipos.ts:4
$
Como dijimos especificamos el tipo number y recibio un string por lo tanto no puede usarlo. Tomemos el codigo y realicemos la siguiente modificacion:
type Registrado = Record< "a" | "b", number | string>;
let registrado: Registrado = {
a: 1,
b: "tinchicus"
};
Esta es una posibilidad que disponemos, no es recomendable pero es valida, donde usaremos una union de tipos para poder permitir dos tipos de datos en esas variables. Por lo tanto ahora la segunda variable pasara a ser valida y podremos compilar perfectamente.
En resumen, hoy hemos visto otras variantes de type mapeado, cuales son, para que sirven, como se utilizan, asi como tambien algunos ejemplos practicos para verlos en accion, espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
