我有一个类型:
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编译器检查的情况下如何处理这种情况?
这个特性被称为“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的另一种选择的答案!
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');
然后,如果您使用这个流而没有定义它,它将立即抛出一个运行时错误。
如果需要,您可以通过添加注释来抑制(下面请注意)
// @ts-ignore:对象可能是空的。
不是对OP的问题的直接回答,但在我的React应用程序与
Typescript - v3.6.2
Tslint - v5.20.0
并使用下面的代码
const refToElement = useRef(null);
if (refToElement && refToElement.current) {
refToElement.current.focus(); // Object is possibly 'null' (for refToElement.current)
}
我通过抑制这一行的编译器继续前进
const refToElement = useRef(null);
if (refToElement && refToElement.current) {
// @ts-ignore: Object is possibly 'null'.
refToElement.current.focus();
}
谨慎
注意,由于这是一个编译器错误而不是linter错误,// tslint:disable-next-line不起作用。此外,根据文档,这应该很少使用,只在必要时使用
更新
在Typescript 3.7之后,你可以使用可选的链接,来解决上面的问题
refToElement?.current?.focus();
此外,有时可能只是在使用useRef时将适当的类型传递给泛型参数的问题。
在输入元素的情况下-
const refToElement = useRef<HTMLInputElement>(null);