'HTMLElement | 类型的参数 null' 不可分配给类型为 'Element' 的参数。类型 'null' 不可分配给类型 'Element'.ts(2345)

kis*_*ore 10 typescript reactjs react-dom

我有 index.html

<body>
    <div id="portal"></div>
    <div id="root"></div>
</body>
Run Code Online (Sandbox Code Playgroud)

并希望使用低于单独的组件portal divroot div

import React from 'react';

const portalDiv = document.getElementById('portal');

function Portal1(props) {
  return ReactDOM.createPortal(
    <div>
      {props.children}
    <div/>, 
  portalDiv); //here
}

export default Portal1;
Run Code Online (Sandbox Code Playgroud)

但我收到此错误,类型为“HTMLElement |的参数” null' 不可分配给类型为 'Element' 的参数。类型 'null'在 VScode 中不能分配给类型 'Element'.ts(2345)

我正在使用打字稿。请帮忙。

Tit*_*lum 33

其他人已经回答说你应该添加一个空检查,但是 Typescript 也有一个非空断言,当你通过在语句的末尾添加运算符来确定值永远不会为空时,你可以使用它!

const portalDiv = document.getElementById('#your-element')!;
Run Code Online (Sandbox Code Playgroud)

  • 是啊,确实不错。(对于添加信息,有时,打字稿,可能是最新的,建议在同一位置使用“?”而不是“!”。工作正常。 (3认同)

小智 28

当我们使用 DOM 树选择 HTMLElement 时,getElementById它会返回文档中与指定选择器匹配的元素,如果没有找到匹配项,它基本上返回 null。

让我们获取门户元素:

let portalDiv = document.getElementById("portal");
Run Code Online (Sandbox Code Playgroud)

如果门户存在于 DOM 树中,它将返回 ,HTMLElemnt如果未找到,则返回null

所以 的返回类型getElementByIdHTMLElement | null,因为 的第二个参数ReactDom.createPrortal(children: ReactNode, element: HTMLElement, id: string)严格来说HTMLElement我们必须将我们的类型强制转换portalDivHTMLElement才能摆脱警告。

由于我们确定portalDivdo 存在,因此我们可以使用此方法来处理条件null

let portalDiv = getElementById("portal") as HTMLElement;
Run Code Online (Sandbox Code Playgroud)

现在我们可以使用portalDiv而不会出现任何错误:

function Portal1(props) {
  return ReactDOM.createPortal(
    <div>
      {props.children}
    <div/>, 
  portalDiv);
}
Run Code Online (Sandbox Code Playgroud)


Olu*_*nwa 9

所以我不知道是否有人仍然遇到这个问题,但有一个更简单直接的解决方案。只需使用“as”关键字声明模态元素即可
const modalRoot = document.getElementById("modal-root") as HTMLElement; 消除错误。我建议查看这个很棒的 react-typescript 备忘单。
https://github.com/typescript-cheatsheets/react


T.J*_*der 8

getElementById可以退货null,但createPortal不接受null

如果您知道门户 div 将存在,请在代码中明确说明这一点:

const portalDiv = document.getElementById('portal');
if (!portalDiv) {
    throw new Error("The element #portal wasn't found");
}
Run Code Online (Sandbox Code Playgroud)

这将允许 TypeScript 缩小常量的类型,删除该| null类型的一部分。如果有人更改了某些内容,导致该代码不再运行时 div 不存在,它还会向您发出很好的主动警告。


tmh*_*005 7

因为getElementById可能返回 null。所以你只需在使用之前简单地检查一下:

function Portal1({ children }) {
  return portalDiv ? ReactDOM.createPortal(<>{children}</>, portalDiv) : null;
}
Run Code Online (Sandbox Code Playgroud)