typescript 如何抑制“错误 TS2533:对象可能是‘空’或‘未定义’”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40349987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:26:19  来源:igfitidea点击:

How to suppress "error TS2533: Object is possibly 'null' or 'undefined'"?

typescript

提问by grasnal

I have a type:

我有一个type

type tSelectProtected = {
  handleSelector?: string,
  data?: tSelectDataItem[],

  wrapperEle?: HTMLElement,
  inputEle?: HTMLElement,
  listEle?: HTMLElement,
  resultEle?: HTMLElement,

  maxVisibleListItems?: number
}

I declare a global module-wise variable:

我声明了一个全局模块变量:

var $protected : tSelectProtected = {};

I'm assigning proper value in function1()scope:

我在function1()范围内分配适当的值:

$protected.listEle = document.createElement('DIV');

Later in function2()scope, I'm calling:

后来在function2()范围内,我打电话给:

$protected.listEle.classList.add('visible');

I'm getting TypeScript error:

我收到打字稿错误:

error TS2533: Object is possibly 'null' or 'undefined'

I know that I can do explicit check using if ($protected.listEle) {$protected.listEle}to calm down compiler but this seems to be very unhandy for most non trivial cases.

我知道我可以使用显式检查if ($protected.listEle) {$protected.listEle}来让编译器冷静下来,但这对于大多数非平凡情况来说似乎非常不方便。

How this situation can or should be handled without disabling TS compiler checks?

在不禁用 TS 编译器检查的情况下如何或应该如何处理这种情况?

采纳答案by Douglas

This feature is called "strict null checks", to turn it off ensure that the --strictNullCheckscompiler flag is not set.

此功能称为“严格空检查”,将其关闭以确保--strictNullChecks未设置编译器标志。

However, the existence of nullhas been describedas The Billion Dollar Mistake, so it is exciting to see languages such as TypeScript introducing a fix. I'd strongly recommend keeping it turned on.

然而,存在null已经被描述十亿美元的错误,所以这是令人兴奋地看到语言如打字稿引入一个修复。我强烈建议保持打开状态。

One way to fix this is to ensure that the values are never nullor undefined, for example by initialising them up front:

解决此问题的一种方法是确保值从不nullundefined,例如通过预先初始化它们:

interface SelectProtected {
    readonly wrapperElement: HTMLDivElement;
    readonly inputElement: HTMLInputElement;
}

const selectProtected: SelectProtected = {
    wrapperElement: document.createElement("div"),
    inputElement: document.createElement("input")
};

See Ryan Cavanaugh's answer for an alternative option, though!

不过,请参阅瑞安·卡瓦诺 (Ryan Cavanaugh) 的答案以获取替代选项!

回答by Ryan Cavanaugh

If you know from external means that an expression is not nullor undefined, you can use the non-null assertion operator !to coerce away those types:

如果您知道从外部意味着一个表达式不是nullor undefined,您可以使用非空断言运算符!来强制删除这些类型:

// Error, some.expr may be null or undefined
let x = some.expr.thing;
// OK
let y = some.expr!.thing;

回答by JoshuaTree

I used:

我用了:

if (object !== undefined) {
    // continue - error suppressed when used in this way.
}

Alternatively, you could use type coercion:

或者,您可以使用类型强制:

const objectX = object as string

Although, before choosing one of the above workarounds, please consider the architecture you are aiming for and it's impact to the bigger picture.

不过,在选择上述解决方法之一之前,请考虑您的目标架构及其对大局的影响。

回答by Vandesh

Not a direct answer to the OP's question, but in my case, I had the following setup -

不是对 OP 问题的直接回答,但就我而言,我进行了以下设置 -

Typescript - v3.6.2
tslint - v5.20.0

打字稿 - v3.6.2
tslint -v5.20.0

And using the following code

并使用以下代码

const refToElement = useRef(null);

if (refToElement && refToElement.current) {
     refToElement.current.focus(); // Object is possibly 'null' (for refToElement.current)
}

I moved on by suppressing the compiler for that line. Note that since it's a compiler error and not the linter error, // tslint:disable-next-linedidn't work. Also, as per the documentation, this should be used rarely, only when necessary-

我通过抑制该行的编译器继续前进。请注意,由于这是编译器错误而不是 linter 错误,// tslint:disable-next-line因此无效。此外,根据文档,这应该很少使用,仅在必要时使用-

const refToElement = useRef(null);

if (refToElement && refToElement.current) {
     // @ts-ignore: Object is possibly 'null'.
     refToElement.current.focus(); 
}

UPDATE:

更新

With Typescript 3.7, you can use optional chaining, to solve the above problem as -

使用 Typescript 3.7,您可以使用optional chaining来解决上述问题 -

refToElement?.current?.focus();

回答by Mahesh Nepal

This solution worked for me:

这个解决方案对我有用:

  • go to tsconfig.jsonand add "strictNullChecks":false
  • 转到tsconfig.json并添加"strictNullChecks":false

enter image description here

在此处输入图片说明

回答by ssube

If you know the type will never be nullor undefined, you should declare it as foo: Barwithout the ?. Declaring a type with the ? Barsyntax means it could potentially be undefined, which is something you need to check for.

如果您知道类型永远不会是nullor undefined,则应该将其声明为foo: Bar没有?. 使用? Bar语法声明类型意味着它可能是未定义的,这是您需要检查的。

In other words, the compiler is doing exactly what you're asking it to. If you want it to be optional, you'll need to the check later.

换句话说,编译器正在做你要求它做的事情。如果您希望它是可选的,则需要稍后进行检查。

回答by thinkOfaNumber

This is not the OP's problem, but I got the same Object is possibly 'null'message when I had declared a parameter as the null type by accident:

这不是 OP 的问题,但是Object is possibly 'null'当我意外地将参数声明为 null 类型时,我得到了相同的消息:

something: null;

instead of assigning it the value of null:

而不是为其分配 null 值:

something: string = null;

回答by Shevchenko Viktor

As an option, you can use a type casting. If you have this error from typescript that means that some variable has type or is undefined:

作为一种选择,您可以使用类型转换。如果打字稿出现此错误,这意味着某些变量具有类型或未定义:

let a: string[] | undefined;

let b: number = a.length; // [ts] Object is possibly 'undefined'
let c: number = (a as string[]).length; // ok

Be sure that areally exist in your code.

确保它a确实存在于您的代码中。

回答by Jonathan Cast CONT

As of TypeScript 3.7 (https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html), you can now use the ?.operator to get undefined when accessing an attribute (or calling a method) on a null or undefined object:

从 TypeScript 3.7 ( https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) 开始,您现在可以使用?.运算符在访问属性(或调用方法)时获取 undefined ) 在 null 或未定义的对象上:

inputEl?.current?.focus(); // skips the call when inputEl or inputEl.current is null or undefined

回答by Gedeon

In ReactJS, I check in the constructor if the variables are null, if they are I treat it like an exception and manage the exception appropriately. If the variables are not null, code carries on and compiler does not complain anymore after that point:

在 ReactJS 中,我在构造函数中检查变量是否为空,如果是,我将其视为异常并适当地管理异常。如果变量不为空,则代码继续执行,并且编译器在此之后不再抱怨:

private variable1: any;
private variable2: any;

constructor(props: IProps) {
    super(props);

    // i.e. here I am trying to access an HTML element
    // which might be null if there is a typo in the name
    this.variable1 = document.querySelector('element1');
    this.variable2 = document.querySelector('element2');

    // check if objects are null
    if(!this.variable1 || !this.variable2) {
        // Manage the 'exception', show the user a message, etc.
    } else {
        // Interpreter should not complain from this point on
        // in any part of the file
        this.variable1.disabled = true; // i.e. this line should not show the error
    }