TypeScript
Type guards nativos
Uso de typeof, instanceof, in, igualdad y truthiness como type guards nativos para refinar valores y trabajar con unions de forma segura.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
- Fundamentos de programación
TypeScript
Uso de typeof, instanceof, in, igualdad y truthiness como type guards nativos para refinar valores y trabajar con unions de forma segura.
function format(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}Valores reconocidos incluyen:
"string""number""bigint""boolean""symbol""undefined""object""function"Recuerda que typeof null === "object".
if (typeof value === "object" && value !== null) {
// object no nulo
}function getMessage(error: Error | string): string {
if (error instanceof Error) {
return error.message;
}
return error;
}Depende del prototipo runtime. Puede fallar entre realms diferentes o con objetos que solo imitan la estructura.
type Animal =
| { swim(): void }
| { fly(): void };
function move(animal: Animal): void {
if ("swim" in animal) {
animal.swim();
} else {
animal.fly();
}
}in comprueba propiedades propias o heredadas.
Si varias variantes permiten una propiedad opcional, pueden permanecer en ambas ramas.
type Human = {
swim?: () => void;
fly?: () => void;
};La presencia opcional no identifica de forma exclusiva una variante.
function normalize(
value: string | string[],
): string[] {
return Array.isArray(value) ? value : [value];
}Es más fiable que instanceof Array entre realms.
if (status === "success") {}Reduce una literal union.
function combine(
first: string | number,
second: string,
) {
if (first === second) {
first.toUpperCase();
}
}TypeScript puede beneficiarse de checks de propiedad, pero Object.hasOwn no siempre reduce una forma desconocida hasta un tipo útil automáticamente. Todavía debes validar el valor.
if (
typeof value === "object" &&
value !== null &&
Object.hasOwn(value, "id")
) {
const id = value.id;
// unknown en configuraciones modernas
}switch (result.status) {
case "success":
return result.data;
case "error":
throw result.error;
}El switch usa igualdad literal para narrowing.
if (user.profile?.name) {}Reduce dentro de la condición, pero también aplica truthiness y puede excluir string vacío.
function invoke(
value: string | (() => string),
): string {
return typeof value === "function"
? value()
: value;
}declare const success: unique symbol;
type Result =
| { type: typeof success; value: Product }
| { type: "error"; error: Error };Un unique symbol también puede actuar como discriminante.
Un type guard nativo suele comprobar solo una pieza.
if (typeof value === "object" && value !== null) {
// todavía no es Product
}Necesitas verificar cada propiedad requerida o delegar a un schema parser.
function parseIdentifier(value: unknown): string | number {
if (
typeof value === "string" ||
typeof value === "number"
) {
return value;
}
throw new TypeError("Invalid identifier");
}"null".typeof, instanceof, in, igualdad y Array.isArray producen narrowing.typeof null es object.instanceof usa prototipos.in incluye la cadena de prototipos.¿Por qué typeof value === "object" no demuestra que value sea Product?
Porque también acepta arrays, Dates y cualquier objeto no funcional, además de null si no lo excluyes. No comprueba las propiedades de Product.
Predicados de tipo y assertion functions permite enseñar al checker comprobaciones propias.