Overwrite `any` in TypeScript when merging interfaces

前端 未结 2 1690
耶瑟儿~
耶瑟儿~ 2021-02-15 15:49

I\'m using Express and I\'m trying to explicitly define res.locals. In the @types/express package, Express.Response.locals is any, so I can\'t seem to

相关标签:
2条回答
  • 2021-02-15 16:38

    Unfortunately there is no way to override any using interface merging. You can so some surgery on the type and replace the type using mapped and conditional types:

    import * as express from 'express'
    
    type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
    
    type MyResponse = Omit<express.Response, "locals"> & { 
      locals: {
        myVar: number
      }
    }
    function middleware(
      req: express.Request, 
      res: MyResponse, 
      next: express.NextFunction
    ) {
      res.locals.myVar = '10' // error now
      next()
    }
    
    0 讨论(0)
  • 2021-02-15 16:53

    I recently ran into this issue and managed to resolve it by creating an index.d.ts in my src folder to overwrite res.locals, my implementation looked like this:

    // src/index.d.ts
    
    interface Locals {
      message?: string;
    }
    
    declare module 'express' {
      export interface Response  {
        locals: Locals;
      }
    }
    

    Make sure you also have it included in your tsconfig.json, e.g

    // somewhere in your tsconfig.json
      "include": [
        "src/**/*.ts"
      ]
    

    You would use the interface just as you would normally

    import { Request, Response, NextFunction } from 'express';
    
    export const handler = (req: Request, res: Response, next: NextFunction) => {
      // should be typed
      res.locals.message = 'hello'
    }
    
    

    Hope this helps!

    0 讨论(0)
提交回复
热议问题