Esta sera una serie de artículos relacionados con TypeScript en el que tratare de explorar las capacidades de TS al mismo tiempo que algunos conceptos de Programación Funcional.
Función Head
function head(array) {
if (array.length === 0) throw new Error("array is empty");
return array[0];
}
head([1, "hello", {}]);
// out: 1, type: any
La función head
nos devuelve el primer elemento de la lista, y en caso de estar vacía nos lanza un Error
aunque también podríamos retornar undefined
, eso ya depende de ti. El problema de head
es que su salida es de tipo any
.
Vamos a intentar arreglar esta situación con TS
function head<T extends any[]>(array: T): Head<T>;
const my_array: [number, string, object] = [1, "hello", {}];
head(my_array);
// out: 1, type: number
Ahora nuestra función es mas segura, head
recibe un parámetro T
restringida en las listas y ademas retorna el primer elemento conservando su tipo (Head<T>
).
Nota: definimos my_array
especificando el tipo de manera explicita, sino lo hacemos así TS deduce my_array
como una unión de los tipos (number | string | object)[]
y no es lo que queremos.
Type HEAD
Veamos que es Head
:
type Head<T extends any[]> = T extends [] ? never : T[0];
Head
toma una lista luego comprobamos si T
es una lista vacía y devolvemos never
, en caso contrario devolvemos el primer elemento de T
. Recuerda que never designa un valor que nunca ocurre y nos viene perfecto para efectos secundarios como lanzar excepciones. También tiene otros usos que veremos después.
Al final quedaría así.
type Head<T extends any[]> = T extends [] ? never : T[0];
function head<T extends any[]>(array: T): Head<T> {
if (array.length === 0) throw new Error("array is empty");
return array[0];
}
head(my_array);
// out: 1, type: number
head([] as []);
// throw Error, type: never
type Number = Head<typeof my_array>
// type: number
Top comments (0)