合并接口时覆盖TypeScript中的“any

ut6juiuv  于 2023-02-25  发布在  TypeScript
关注(0)|答案(3)|浏览(146)

我正在使用Express,并试图显式定义res.locals,在@types/express包中,Express.Response.locals是any,所以我似乎无法覆盖它:
类型/表达式/索引。d.ts:

declare namespace Express {
  interface Response {
    locals: {
      myVar: number
    }
  }
}

我的中间件:

import * as express from 'express'

function middleware(
  req: express.Request, 
  res: express.Response, 
  next: express.nextFunction
) {
  res.locals.myVar = '10' // I want this to throw a compiler error
  next()
}

我想把错误的res.locals.myVar赋值给error,但是根据我的自动完成,res.locals仍然是any
如何删除any并完全替换它?

8xiog9wr

8xiog9wr1#

我最近遇到了这个问题,通过在src文件夹中创建一个index.d.ts来覆盖res.locals,成功地解决了这个问题,我的实现如下所示:

// src/index.d.ts
import 'express';

interface Locals {
  message?: string;
}

declare module 'express' {
  export interface Response  {
    locals: Locals;
  }
}

确保您的tsconfig.json中也包含了它,例如

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

您可以像平常一样使用该界面

import { Request, Response, NextFunction } from 'express';

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

希望这有帮助!

bt1cpqcv

bt1cpqcv2#

不幸的是,没有办法使用接口合并来覆盖任何类型。你可以对类型做一些手术,用Map类型和条件类型来替换类型:

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()
}
bihw5rsg

bihw5rsg3#

当前接受的答案(https://stackoverflow.com/a/57509904/5043802)已过时且已损坏。新的解决方案是将以下内容添加到项目中的*.d.ts文件(包含在tsconfig中):

// src/index.d.ts
declare global {
  namespace Express {
    interface Locals {
      shopify: { session: Session }
    }
  }
}

有关说明,请访问https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b986359dc0a8a2108b777c3eb7d3d51909408631/types/express-serve-static-core/index.d.ts#L16

相关问题