express - Cómo sobrescribir una interfaz externa de TypeScript
Estoy usando passport en un proyecto de TypeScript. La definición de tipos de DefinitelyTyped para passport sobrescribe la solicitud de Express para incluir la propiedad user. Pero define el usuario como una interfaz vacía:
index.d.tsdeclare global {
namespace Express {
...
// tslint:disable-next-line:no-empty-interface
interface User {}
interface Request {
...
user?: User;
...
}
}
}
Sin embargo, a lo largo de mi aplicación quiero que req.user sea de este tipo de interfaz:
interface User {
id: number
username: string,
profilePicture: string,
name: string
}
Estoy cansado de escribir req.user as User | null en toda mi aplicación. Podría sobrescribir la definición de la interfaz directamente en el archivo de definiciones, pero esto parece una mala práctica al modificar un archivo en node_modules que probablemente se sobrescriba si actualizo el módulo de tipos.
¿Hay alguna manera de escribir un archivo de definiciones en mi carpeta src que sobrescriba Express.User? He intentado copiar y modificar el archivo de definiciones en mi directorio src, pero dice
Augmentations for the global scope can only be directly nested in external modules or ambient module declarationsSin declare global, tsc todavía trata req.user como si fuera de una interfaz vacía.
¿Qué configuración tengo que incluir en tsconfig.json para luego aplicar esta sobrescritura?
Respuesta #1
Las declaraciones de interfaz en el mismo ámbito se fusionan. Es decir, lo siguiente
interface A {
name: string;
}
interface A {
id: number;
}
declara una única interfaz, a saber, A, con dos propiedades, name y id.
Por lo tanto, simplemente usa la misma técnica que usa el pasaporte para ajustar los tipos.
Mi convención es crear un archivo de aumentos en la raíz de mi proyecto cuando quiero aumentar las declaraciones de tipo de cualquier dependencia como express.
augmentaciones.d.ts
// ensure file is parsed as a module
export {}
// access the global scope inside our module
declare global {
namespace Express {
// introduce another declaration of interface Express.User which will merge with any others
interface User {
id: number,
username: string,
profilePicture: string,
name: string
}
}
}
