我有一个类型:

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

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

  maxVisibleListItems?: number
}

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

var $protected : tSelectProtected = {};

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

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

稍后在function2()作用域中,我调用:

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

我得到TypeScript错误:

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

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

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


当前回答

RxJS的提示

我经常会有Observable<string>类型的成员变量,直到ngOnInit(使用Angular)我才会初始化它。然后编译器假设它是未初始化的,因为它没有“在构造函数中明确赋值”——并且编译器永远不会理解ngOnInit。

你可以使用!定义上的断言运算符,以避免错误:

favoriteColor!: Observable<string>;

未初始化的可观察对象会导致各种运行时错误,比如“你必须提供一个流,但你提供了null”。!如果你明确知道它将被设置在ngOnInit这样的东西中是可以的,但也可能有一些情况,值以其他不那么确定的方式设置。

所以我有时会使用的替代方法是:

public loaded$: Observable<boolean> = uninitialized('loaded');

其中uninitialized被全局定义为:

export const uninitialized = (name: string) => throwError(name + ' not initialized');

然后,如果您使用这个流而没有定义它,它将立即抛出一个运行时错误。

其他回答

如果你知道该类型永远不会为null或未定义,你应该声明为foo: Bar,不带?类型声明?条形语法意味着它可能是未定义的,这是您需要检查的。

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

这个特性被称为“strict null checks”,关闭它时要确保没有设置编译器标志——strictNullChecks。

然而,null的存在被描述为“十亿美元的错误”,所以看到像TypeScript这样的语言引入修复是令人兴奋的。我强烈建议你把它开着。

解决这个问题的一种方法是确保值永远不是null或undefined,例如通过预先初始化它们:

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

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

不过,请参阅Ryan Cavanaugh的另一种选择的答案!

作为一个选项,您可以使用类型强制转换。如果你从typescript中得到这个错误,这意味着某些变量有类型或未定义:

let a: string[] | undefined;

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

确保代码中确实存在a。

像这样绑定变量variabalName?它肯定会起作用的。

对我来说,这是裁判和反应的错误:

const quoteElement = React.useRef()
const somethingElse = quoteElement!.current?.offsetHeight ?? 0

这将抛出错误,修复,给它一个类型:

// <div> reference type
const divRef = React.useRef<HTMLDivElement>(null);

// <button> reference type
const buttonRef = React.useRef<HTMLButtonElement>(null);

// <br /> reference type
const brRef = React.useRef<HTMLBRElement>(null);

// <a> reference type
const linkRef = React.useRef<HTMLLinkElement>(null);

没有错误了,希望这能在某种程度上帮助到其他人,甚至是我自己,P