Aplica los patrones de experto que aseguran una base de código real: nominalidad simulada, validación sin ampliación y declaraciones ambientales.
Abrir esta lección en KodokonEl tipado de TypeScript es estructural: dos tipos con la misma forma son intercambiables, por lo que un string de id de usuario es indistinguible de cualquier otro string. El branding simula el tipado nominal intersecando el tipo base con una propiedad fantasma cuya clave es un unique symbol: ningún valor real la tiene nunca, pero el compilador ahora distingue cada marca.
declare const brand: unique symbol;
type Brand<T, Name extends string> =
T & { readonly [brand]: Name };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
function asUserId(raw: string): UserId {
return raw as UserId;
}
declare function loadUser(id: UserId): void;
loadUser(asUserId("u_42")); // OK
// loadUser("u_42"); // error: bare string rejectedEl operador satisfies (TypeScript 4.9) cubre una carencia precisa. Una anotación : T amplía el tipo de la variable a T y pierde los literales inferidos; un as T desactiva parte de las comprobaciones. satisfies T verifica que la expresión se ajusta a T sin tocar el tipo inferido, que se mantiene tan preciso como sea posible. Es la herramienta ideal para objetos de configuración: validación completa, precisión intacta.
type RouteDef = { path: string; auth?: boolean };
const routes = {
home: { path: "/" },
admin: { path: "/admin", auth: true },
} satisfies Record<string, RouteDef>;
routes.admin.auth;
// literal type true: the inferred precision is
// preserved, and an unknown key would be rejectedUn archivo .d.ts contiene declaraciones ambientales exclusivamente: describe valores que existirán en tiempo de ejecución, sin emitir una sola línea de JavaScript. Para extender el ámbito global desde un módulo, el bloque declare global es obligatorio - y la especificación solo lo permite en un archivo que realmente sea un módulo, de ahí el idioma export {} al principio del archivo.
export {};
declare global {
interface Window {
analytics: { track(event: string): void };
}
}Para una dependencia de JavaScript sin tipos publicados, declare module crea un módulo ambiental: el compilador usará tu declaración para cada importación del paquete. Cuidado con el alcance de skipLibCheck: cuando está activado, ignora los errores de todos los archivos .d.ts, incluidos los tuyos; así que verifica tus declaraciones mediante tests de tipos colocados en archivos .ts ordinarios.
declare module "legacy-lib" {
export interface InitOptions {
debug?: boolean;
}
export function init(options?: InitOptions): void;
}satisfies T y una anotación : T?Brand<string, ...>?export {} al principio de un archivo .d.ts que usa declare global?