如何在Typescript中覆盖属性不可为空

时间:2016-11-01 23:30:50

标签: node.js typescript typescript-typings

Node内置IncomingMessage的DefinitelyTyped定义((req, res, next)参数中的req类型)定义了url to be nullable。这是定义文件的剪切部分:

// @types/node/index.d.ts
declare module "http" {
  export interface IncomingMessage {
    /**
     * Only valid for request obtained from http.Server.
     */
    url?: string;
  }
}

正如评论所说,这是因为只有当您从http.Server获取此IncomingMessage的实例时,此属性才有效。在其他用途​​中,它不会存在,因此,它可以为空。

但是,在我的情况下,我知道我只是从http.Server获取这些实例,所以它有点烦人我不能在没有额外警卫的情况下进入酒店。

import { IncomingMessage, ServerResponse } from 'http';

function someMiddleware(req: IncomingMessage, res: ServerResponse, next: Function) {
  const myStr: string = req.url; // bzzzt.
  // Argument of type 'string | undefined' is not
  // assignable to parameter of type 'string'.
}

我很高兴提到我使用的是带有strictNullChecks的TS 2.0.3,Typescript Playground未启用。 < / p>

这是问题所在。 是否可以在我的应用程序中覆盖该定义,以便url不可为空?

这是我已经尝试过的...将其添加到我的某个文件中:

declare module 'http' {
  interface IncomingMessage {
    url: string;
  }
}

...但是这是不允许的:&#34;后续变量声明必须具有相同的类型&#34;。 This is explained in the documentation.

到目前为止,我唯一能想到的是创建自己的模块,导入,扩展然后导出接口:

// /src/http.ts
import { IncomingMessage as OriginalIM } from 'http';
export interface IncomingMessage extends OriginalIM {
  url: string;
}

// src/myapp.ts
import { IncomingMessage } from './http'; // <-- local def

function someMiddleware(req: IncomingMessage) {
  const str: string = req.url; // all good
}

所以,这有效,但似乎错了。

2 个答案:

答案 0 :(得分:1)

所以我找到了一个稍微不那么hacky的解决方案。

TypeScript 2.0还添加了non-null assertion operatorIO[String]

!

在我的情况下,它仍然有点烦人,因为有许多不同的文件需要访问这个属性,所以这个非空的断言在很多地方使用。

答案 1 :(得分:0)

从TypeScript 2.1开始,您可以使用查找类型来访问接口属性。

IncomingMessage['url'] // string | undefined

您可以将其与NonNullable结合使用以适应您的用例。

NonNullable<IncomingMessage['url']> // string

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html