类型“HTMLElement 或 null”不可分配给 TS 中的类型

目录

Type ‘HTMLElement or null’ is not assignable to type in TS

  1. 类型“HTMLElement 或 null”不可分配给 TS 中的类型
  2. “HTMLElement”类型的参数不可分配给 TS 中的类型
  3. (反应)参数类型“HTMLElement 或 null”不可分配给参数类型“Element 或 DocumentFragment”

Type ‘HTMLElement or null’ 不可分配给 TS 中的类型

null当将可能的值分配给需要元素的对象时,会发生“Type ‘HTMLElement | null’ is not assignable to type”错误。

要解决该错误,请在赋值之前使用非空断言或类型保护来验证该值是一个元素。

htmlelement 或 null 不可分配类型

这是示例的 HTML 代码。

索引.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> </head> <body> <input id="submit" type="submit" name="submit" /> <script src="./src/index.ts"></script> </body> </html>

这里有 3 个错误发生的例子。

源代码/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); // ⛔️ Type 'HTMLElement | null' is not assignable to type 'HTMLElement'. // Type 'null' is not assignable to type 'HTMLElement'.ts(2322) const el1: HTMLElement = input; // --------------------------------------- // ⛔️ Type 'HTMLElement | null' is not assignable to type 'Element'. // Type 'null' is not assignable to type 'Element'.ts(2322) const el2: Element = input; // --------------------------------------- function example(el: Element) { return el; } // ⛔️ Argument of type 'HTMLElement | null' is not assignable // to parameter of type 'Element'. // Type 'null' is not assignable to type 'Element'.ts(2345) example(input);

input变量的类型为HTMLElement | null.

变量的类型为and ,因此它们只希望el1获得该类型的值。el2HTMLElementElement

TypeScript 基本上是在告诉我们input变量的值可能null只需要. el1HTMLElement

使用非空断言运算符

以下是如何解决错误的几个示例。

源代码/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const el1: HTMLElement = input!; // 👈️ non-null assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const el2: Element = input!; // 👈️ non-null assertion function example(el: Element) { return el; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion example(input!); // 👈️ non-null assertion

感叹号是
TypeScript 中的
非空断言运算符。

在不进行任何显式类型检查的情况下从类型中删除null和。undefined

当你使用这种方法时,你基本上告诉 TypeScript 这个值永远不会是nullor undefined

使用类型断言

这与
类型断言非常相似
,只有在您绝对确定该值属于预期类型时才应使用。

源代码/index.ts
const input = document.getElementById('submit'); const el1: HTMLElement = input as HTMLElement; // 👈️ type assertion const el2: Element = input as Element; // 👈️ type assertion function example(el: Element) { return el; } example(input as HTMLElement); // 👈️ type assertion

当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

我们有效地告诉 TypeScript 这el1将是一个并且不用担心它。 HTMLElement

您还可以在选择元素时直接使用类型断言。

源代码/index.ts
// 👇️ used type assertion here const input = document.getElementById('submit') as HTMLInputElement; const el1: HTMLElement = input; const el2: Element = input; function example(el: Element) { return el; } example(input);

我们将input元素键入为有效地
从其类型中
HTMLInputElement移除。null

这些类型的名称一致HTML***Element一旦您开始输入
HTML..,您的 IDE 应该能够帮助您自动完成。

一些常用的类型有:HTMLInputElementHTMLButtonElement
HTMLAnchorElementHTMLImageElementHTMLDivElement
HTMLTextAreaElement等。

使用类型保护来解决错误

另一种更好的方法是使用
类型保护

源代码/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); function example(el: Element) { return el; } if (input != null) { const el1: HTMLElement = input; const el2: Element = input; example(input); }

if语句用作类型保护。我们明确检查input
变量是否不存储
null值。

源代码/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); // 👉️ input has type HTMLElement or null here if (input != null) { // 👉️ input has type HTMLElement here const el1: HTMLElement = input; const el2: Element = input; example(input); } function example(el: Element) { return el; }

TypeScript 知道变量
块中
input的类型,并允许我们直接将其分配给变量。HTMLElementifel1el2

类型为“HTMLElement”的参数不可分配给 TS 中的类型

使用类型断言解决“’HTMLElement’ 类型的参数不可分配给类型的参数”错误。

传入参数和预期参数的类型必须兼容。

参数类型 htmlelement 不可分配参数

以下是错误发生方式的 2 个示例。

索引.ts
const element = document.getElementById('example') as HTMLElement; function example1(el: HTMLInputElement) { return el; } // ⛔️ Argument of type 'HTMLElement' is not assignable // to parameter of type 'HTMLInputElement'. example1(element); // ----------------------------------------------- function example2(el: HTMLCanvasElement) { return el; } // ⛔️ Argument of type 'HTMLElement' is not assignable // to parameter of type 'HTMLCanvasElement'. example2(element);

第一个示例中出现错误的原因是该函数需要一个 type 的参数HTMLInputElement,而我们向它传递了一个 type 的参数
HTMLElement

在第二个示例中,该函数需要一个 type 的参数
HTMLCanvasElement,我们向它传递一个 type 的参数HTMLElement

使用类型断言解决错误

我们可以使用类型断言来解决错误。

索引.ts
const element = document.getElementById('example') as HTMLElement; function example1(el: HTMLInputElement) { return el; } example1(element as HTMLInputElement); // 👈️ type assertion function example2(el: HTMLCanvasElement) { return el; } example2(element as HTMLCanvasElement); // 👈️ type assertion
您必须使用错误消息中提到的特定参数类型。

当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

我们有效地告诉 TypeScriptelement变量存储了一个特定类型的值,不用担心。

您必须在类型断言中使用的类型是函数参数的类型。

“’HTMLElement’ 类型的参数不可分配给类型的参数”错误的原因是我们将类型的参数传递HTMLElement给具有不同类型参数的函数。

您还可以在选择元素时使用类型断言。

索引.ts
// 👇️ use type assertion here const element = document.getElementById('example') as HTMLInputElement; function example1(el: HTMLInputElement) { return el; } example1(element);

我们将element变量键入为HTMLInputElement元素,这是函数期望的类型example1

在调用函数时,我们必须确保传入参数的类型与预期参数的类型兼容。

用联合加宽参数类型

或者,您可以使用联合类型扩大函数参数的类型

源代码/index.ts
const element = document.getElementById('example') as HTMLElement; function example1(el: HTMLInputElement | HTMLElement) { return el; } example1(element);

示例函数需要一个HTMLInputElementor
类型的参数
HTMLElement,因此向它传递一个 type 的参数HTMLElement可以满足预期的参数类型。

(React) 参数类型“HTMLElement 或 null”不可分配给参数类型“Element 或 DocumentFragment”

使用非空断言或类型断言来解决 React.js 错误“Argument of type ‘HTMLElement | null’ is not assignable to parameter of type ‘Element | DocumentFragment’”,例如const root = createRoot(rootElement!)

参数类型 htmlelement 或 null 不可分配



下面是错误如何发生的示例。

索引.tsx
import App from './App'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; const rootElement = document.getElementById('root'); // ⛔️ Argument of type 'HTMLElement | null' is not // assignable to parameter of type 'Element | DocumentFragment'. // Type 'null' is not assignable to type 'Element | DocumentFragment'.ts(2345) const root = createRoot(rootElement); root.render( <StrictMode> <App /> </StrictMode>, );

这里的问题是
document.getElementById方法的返回类型是HTMLElement | null

如果提供的 id 在 DOM 中不存在,则该方法返回 null

另一方面,
createRoot方法的预期参数类型是
Element | DocumentFragment,因此提供的参数类型与预期参数类型不匹配。



解决该错误的一种方法是使用
非空 (!)
断言运算符。

索引.tsx
import App from './App'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; const rootElement = document.getElementById('root'); // 👇️ non-null (!) assertion const root = createRoot(rootElement!); root.render( <StrictMode> <App /> </StrictMode>, );
非空 (!) 断言运算符从类型中删除null和删除而不进行任何显式类型检查。 undefined

当你使用这种方法时,你基本上告诉 TypeScript 该rootElement
变量永远不会是
nullor undefined因此,rootElement变量变成了 typeHTMLElement而不是HTMLElement | null.

或者,您可以使用简单的
类型断言

索引.tsx
import App from './App'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; const rootElement = document.getElementById('root'); // 👇️ use type assertion const root = createRoot(rootElement as Element); root.render( <StrictMode> <App /> </StrictMode>, );



当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

我们实际上是在告诉 TypeScriptrootElement变量存储了一个类型的值Element,不用担心它。

我们从错误消息中确定了正确的类型:“‘HTMLElement | null’类型的参数不可分配给‘Element | DocumentFragment’类型的参数”。

通过此错误消息,TypeScript 告诉我们:函数的预期参数类型为Element | DocumentFragment,但您正在使用类型为参数调用该函数HTMLElement | null

类型不兼容,因为参数类型可能是null

要解决该错误,我们必须使传入的参数和预期的参数类型兼容。

额外资源

您可以通过查看以下教程来了解有关相关主题的更多信息: