Sobrecarga de funciones en TypeScript vs uso de un tipo unión
Estoy leyendo sobre sobrecargas de funciones. Esencialmente, lo que son es, estás creando, digamos, 3 funciones con el mismo nombre, que están pasando 3 parámetros diferentes y tipos de retorno diferentes. Soy nuevo en TS y me preguntaba lo siguiente: ¿no sería lo mismo pasar un tipo unión y retornar un tipo unión? ¿O es algo completamente diferente?
Esto es lo que se me ocurrió en la cabeza como un ejemplo. ¿Funcionaría esto o no?
Sobrecarga:
function f1(a: string) {
}
function f1(a: number) {
}
Usando un tipo unión:
function f1(a: string | number):string | number {
}
Respuesta #1
La sobrecarga de funciones asigna un tipo de entrada específico a un tipo de retorno específico. Con una unión solo sabes que el retorno es uno de los tipos válidos, pero pierdes la asociación entre la entrada y la salida. Esto puede o no ser un problema dependiendo de cómo y dónde uses la función. Pero esa es la diferencia.
Así es como se ve con sobrecargas. La última línea de la firma no es una de las sobrecargas, describe los tipos para la implementación. A veces verás any, pero también puedes usar la unión aquí.
function overloaded(a: string): string
function overloaded(a: number): number
function overloaded(a: any): any {
return a;
}
Los diferentes argumentos devuelven el tipo específico según la sobrecarga con la que coincidan.
const oNum: number = overloaded(0);
const oStr: string = overloaded("");
const oBool = overloaded(true); //error
En nuestra unión, ambos tipos de entrada simplemente devuelven la unión, por lo que hemos perdido la especificidad.
function union(a: string | number): string | number {
return a;
}
const uNum: string | number = union(0);
const uStr: string | number = union("");
const uBool = union(true); //error
Hay una tercera opción que son los genéricos de TypeScript. Esto nos permite mantener la especificidad mientras aceptamos infinitos tipos. El ejemplo de boolean funciona ahora. Le estamos diciendo a TypeScript "mira el tipo del argumento a y llama a eso T". Luego obtenemos esta variable de tipo T que podemos usar en el tipo de retorno. Aquí simplemente estamos devolviendo el mismo tipo T directamente, pero hay mucho más que se puede hacer con él.
function generic<T>(a: T): T {
return a;
}
const gNum: number = generic(0);
const gStr: string = generic("");
const gBool: boolean = generic(true);
Enlace de Playground de Typescript
