目录
Type ‘HTMLElement or null’ is not assignable to type in TS
- 类型“HTMLElement 或 null”不可分配给 TS 中的类型
- “HTMLElement”类型的参数不可分配给 TS 中的类型
- (反应)参数类型“HTMLElement 或 null”不可分配给参数类型“Element 或 DocumentFragment”
Type ‘HTMLElement or null’ 不可分配给 TS 中的类型
null
当将可能的值分配给需要元素的对象时,会发生“Type ‘HTMLElement | null’ is not assignable to type”错误。
要解决该错误,请在赋值之前使用非空断言或类型保护来验证该值是一个元素。
这是示例的 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 个错误发生的例子。
// 👇️ 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
获得该类型的值。el2
HTMLElement
Element
input
变量的值可能null
与只需要. el1
HTMLElement
使用非空断言运算符
以下是如何解决错误的几个示例。
// 👇️ 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 这个值永远不会是null
or undefined
。
使用类型断言
这与
类型断言非常相似
,只有在您绝对确定该值属于预期类型时才应使用。
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 不知道的值类型的信息时,使用类型断言。
el1
将是一个并且不用担心它。 HTMLElement
您还可以在选择元素时直接使用类型断言。
// 👇️ 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 应该能够帮助您自动完成。
一些常用的类型有:HTMLInputElement
、HTMLButtonElement
、
HTMLAnchorElement
、HTMLImageElement
、HTMLDivElement
、
HTMLTextAreaElement
等。
使用类型保护来解决错误
另一种更好的方法是使用
类型保护。
// 👇️ 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
值。
// 👇️ 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
的类型,并允许我们直接将其分配给和变量。HTMLElement
if
el1
el2
类型为“HTMLElement”的参数不可分配给 TS 中的类型
使用类型断言解决“’HTMLElement’ 类型的参数不可分配给类型的参数”错误。
传入参数和预期参数的类型必须兼容。
以下是错误发生方式的 2 个示例。
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
。
使用类型断言解决错误
我们可以使用类型断言来解决错误。
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
给具有不同类型参数的函数。
您还可以在选择元素时使用类型断言。
// 👇️ use type assertion here const element = document.getElementById('example') as HTMLInputElement; function example1(el: HTMLInputElement) { return el; } example1(element);
我们将element
变量键入为HTMLInputElement
元素,这是函数期望的类型example1
。
用联合加宽参数类型
或者,您可以使用联合类型扩大函数参数的类型
。
const element = document.getElementById('example') as HTMLElement; function example1(el: HTMLInputElement | HTMLElement) { return el; } example1(element);
示例函数需要一个HTMLInputElement
or
类型的参数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!)
。
下面是错误如何发生的示例。
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
。
null
另一方面,
createRoot方法的预期参数类型是
Element | DocumentFragment
,因此提供的参数类型与预期参数类型不匹配。
解决该错误的一种方法是使用
非空 (!)
断言运算符。
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
变量永远不会是null
or undefined
。因此,rootElement
变量变成了 typeHTMLElement
而不是HTMLElement | null
.
或者,您可以使用简单的
类型断言。
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’类型的参数”。
Element | DocumentFragment
,但您正在使用类型为参数调用该函数HTMLElement | null
。类型不兼容,因为参数类型可能是null
。
要解决该错误,我们必须使传入的参数和预期的参数类型兼容。
额外资源
您可以通过查看以下教程来了解有关相关主题的更多信息: