如何在 Typescript 中将属性覆盖为不可为空 [英] How to override a property to be non-nullable in Typescript

查看:58
本文介绍了如何在 Typescript 中将属性覆盖为不可为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Node 内置 IncomingMessage 的绝对类型定义((req, res, next) 参数中的 req 类型)已经定义了 url 可以为空.以下是定义文件的片段:

The DefinitelyTyped definition of the Node built-in IncomingMessage (the type of req in the (req, res, next) arguments) has defined url to be nullable. Here's the snipped parts of the definition file:

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

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

As the comment says, this is because this property is only valid when you're getting an instance of this IncomingMessage from the http.Server. In other uses it won't exist, hence, it's nullable.

但是,就我而言,我知道我只能从 http.Server 获取这些实例,因此我无法在没有额外保护的情况下访问该属性,这有点烦人.

However, in my case, I know that I'm only getting these instances from http.Server, and so it's kinda annoying that I can't just access the property without extra guards.

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.

It's probably good to mention that I'm using TS 2.0.3 with strictNullChecks, which is not enabled on the Typescript Playground.

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

Here's the question. Is it possible to override that definition across my application so that url is not nullable?

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

Here's what I've already tried... adding this to one of my files:

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

...但是这是不允许的:后续变量声明必须具有相同的类型".文档中对此进行了说明.

...however that is disallowed: "Subsequent variable declarations must have the same type". This is explained in the documentation.

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

The only thing I can think of thus far is to create my own module which imports, extends and then exports the interfaces:

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

所以,这行得通,但似乎错了.

So, this works, but it seems so wrong.

推荐答案

所以我找到了一个稍微不那么麻烦的解决方案.

So I found a solution which is slightly less hacky.

TypeScript 2.0 还添加了一个 非空断言运算符:!

TypeScript 2.0 also has added a non-null assertion operator: !

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

就我而言,它仍然有点烦人,因为有许多不同的文件需要访问此属性,因此该非空断言在许多地方使用.

In my case, it's still a bit annoying, since there are many different files which need to access this property and so this non-null assertion is used in many places.

这篇关于如何在 Typescript 中将属性覆盖为不可为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆