document.getElementById("id") 可能为 null

问题描述 投票:0回答:5

编辑:我正在使用 TypeScript v2.2.1

我是 TypeScript 新手,我不确定处理可能存在或可能不存在的 DOM 元素的最简洁方法是什么。基本上,我想检查一个元素是否存在,然后如果存在,则向其添加一个事件侦听器(我已打开

--strict_null_checks
)。

当我用类似 JS 的方式做的时候:

const myElement = document.getElementById('my-id');
if (myElement) {
  myElement.addEventListener('click', (e:Event) => {
    // Do stuff.
  });
}

我收到错误

my_script.ts(3, 3): error TS2531: Object is possibly 'null'.

我可以通过使用非空断言来解决这个问题:

const maybeMyElement = document.getElementById('my-id');
if (maybeMyElement) {
  const myElement = maybeMyElement!;
  myElement.addEventListener('click', (e:Event) => {
    // Do stuff.
  });
}

但我的理解是,这类断言通常会令人不悦,而且从美学角度来看,我不喜欢创建两倍的变量。

有没有更干净的方法来做到这一点?

typescript typescript2.0
5个回答
34
投票

您应该输入变量。我没有对

const
做太多事情,但你的第二个选项似乎完全错误(代码气味)。

您应该能够通过严格输入变量来绕过警告。编译器当前将此视为

const myElement: HTMLElement = document.getElementById('my-id');

如果您将其更改为也可能为空,则允许空值:

const myElement: HTMLElement | null = document.getElementById('my-id');

已更新

第二个选项(我没有尝试过):在可能为空的操作结束时使用

!
,根据 https://stackoverflow.com/a/40640854/2084315

const myElement = document.getElementById('my-id')!;

6
投票

使用可选链接“?”

从 TypeScript 版本 3.7+ 开始,您可以使用 可选链接

const maybeMyElement = document.getElementById('my-id');
maybeMyElement?.addEventListener('click', (e: Event) => {
  // Do stuff.
  console.log(e);
});

对于旧版本的 TypeScript,我们会做类似的事情

const maybeMyElement = document.getElementById('my-id') as HTMLElement;
maybeMyElement.addEventListener('click', (e: Event) => {
  // Do stuff.
  console.log(e);
});

注意: 可选链接 (??) 始终优于非空断言运算符 (!),因为如果值为空或未定义,非空断言实际上可能会导致运行时错误。

并且,如果您在 eslint 设置中配置了“plugin:@typescript-eslint/recommended”,您将在代码中收到“禁止非空断言”警告。


5
投票

尝试使用以下方法:

if (!!myElement) {
    myElement.addEventListener('click', (e:Event) => {
        // Do stuff.
    });
}

!!
将对象表达式强制转换为布尔值。这是
!
运算符两次。有关这方面的更多信息,请参阅此答案


0
投票

如果您使用引用外部 JS 文件,请尝试在脚本语法中添加“defer”。 例如:

<script src="./script.js" defer></script>

0
投票

ReactJS 与 Typescript 以下答案适用于 DOM 操作

var myModal = document.getElementById('idelement') as HTMLElement;
myModal.getAttribute('style');
© www.soinside.com 2019 - 2024. All rights reserved.