En los programas se hace necesario tomar decisiones basadas en los valores de entrada. En JavaScript esto también es así, y considerando que los valores pueden ser fácilmente determinados, dichas decisiones también están basadas en los valores de entrada.
Los tipos condicionales describen la relación entre los valores de entrada y los de salida.
interface Animal {
live(): void;
}
interface Perro extends Animal {
ladrar(): void;
}
type E1 = Perro extends Animal ? number : string;
// E1 = number porque Perro extiende de animal
type E2 = RegExp extends Animal ? number : string;
// E2 = string porque RegExp no extiende de Animal
Los tipos condicionales toman una forma que luce como expresiones condicionales con el operador ternario (condition ? expresionVerdadera : expresionFalsa
).
condicion ? tipoSiEsVerdadero : tipoSiEsFalso;
Supongamos que deseamos una impresora de etiquetas, esta soporta dos tipos de etiquetas: las etiquetas que imprimen un identificador numérico y las que usan una combinación de números y letras.
interface IdEtiqueta {
id: number;
}
interface NombreEtiqueta {
nombre: string;
}
function crearEtiqueta(arg: number): IdEtiqueta;
function crearEtiqueta(arg: string): NombreEtiqueta;
function crearEtiqueta(arg: string | number): IdEtiqueta | NombreEtiqueta;
function crearEtiqueta(arg: string | number): IdEtiqueta | NombreEtiqueta {
throw "sin implementar";
}
crearEtiqueta("randomId");
crearEtiqueta(10000477);
Hemos utilizado sobrecarga para crear una función que reciba un valor arg
como número o string, y en base a ello podemos abstraer la lógica necesaria para desarrollar cada uno de los casos.
Otra forma de solucionar este mismo problema es utilizando conditional types.
type Arg<T extends string | number> = T extends number
? IdEtiqueta
: NombreEtiqueta;
function crearEtiquetaSimplificado<T extends string | number>(arg: T): Arg<T> {
throw "sin implementar aun";
}
crearEtiquetaSimplificado("randomId");
crearEtiquetaSimplificado(10000477);