Node.js 如何在Typescript中重写不可为null的属性

Node.js 如何在Typescript中重写不可为null的属性,node.js,typescript,typescript-typings,Node.js,Typescript,Typescript Typings,节点内置IncomingMessage的DefinitelyTyped定义((req,res,next)参数中的req类型)已经定义。以下是定义文件中被剪断的部分: // @types/node/index.d.ts declare module "http" { export interface IncomingMessage { /** * Only valid for request obtained from http.Server. */ url

节点内置IncomingMessage的DefinitelyTyped定义(
(req,res,next)
参数中的req类型)已经定义。以下是定义文件中被剪断的部分:

// @types/node/index.d.ts
declare module "http" {
  export interface IncomingMessage {
    /**
     * Only valid for request obtained from http.Server.
     */
    url?: string;
  }
}
正如注释所述,这是因为只有当您从http.Server获取此IncomingMessage的实例时,此属性才有效。在其他用途中,它不存在,因此可以为null

然而,在我的例子中,我知道我只从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'.
}
我使用的TS 2.0.3带有
strictNullChecks
,这在上没有启用,这一点可能很好

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


这是我已经尝试过的。。。将此添加到我的一个文件:

declare module 'http' {
  interface IncomingMessage {
    url: string;
  }
}
…但是这是不允许的:“后续变量声明必须具有相同的类型”

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

// /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
}
///src/http.ts
从“http”导入{incomingmessageasoriginalim};
导出接口IncomingMessage扩展了原始语言{
url:string;
}
//src/myapp.ts

从“./http”;/”导入{IncomingMessage} 因此,我找到了一个稍微不那么老套的解决方案

TypeScript 2.0还添加了一个:

function someMiddleware(req: IncomingMessage) {
  const str1: string = req.url;  // error, can't assign string | undefined to string
  const str2: string = req.url!; // works
}

在我的例子中,这仍然有点烦人,因为有许多不同的文件需要访问此属性,因此此非空断言在许多地方都使用。

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

IncomingMessage['url'] // string | undefined
您可以将其与
不可为空
相结合,以适合您的用例

NonNullable<IncomingMessage['url']> // string
不可为空//字符串

感谢您指出这一点!我只为那些可能不关注你链接的人添加了
运算符声明非空和非未定义。此运算符应仅在类型检查器由于业务逻辑而无法得出该事实结论的上下文中使用。在任何地方都使用它作为一个规则可能会让人困惑。我想,如果您确信此对象属性始终存在,那么您所做的并没有错。当然比在代码中到处强制转换这种类型要好。