Búsqueda de sitios web

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.ts
declare 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 declarations

Sin 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
    }
  }
}

Artículos relacionados