如何解决 TS 中的'Object possibly null'错误?



我有类似的问题,使用 Draft.js 和 React 和 Typescript。 使用与他们的文档示例相同的代码,我在focusEditor函数中得到Object is possibly 'null'错误。即使我检查空引用,它仍然存在(就像我上面引用的 SO 问题中的解决方案一样(。下面是添加了空检查的代码:

import React from 'react';
import { Editor, EditorState } from 'draft-js';
export default () => {
const [editorState, setEditorState] = React.useState(
EditorState.createEmpty()
);
const editor = React.useRef(null);
function focusEditor() {
if (null === editor) {
throw Error('editor is null') 
}
if (null === editor.current) {
throw Error('editor.current is null') 
}
editor.current.focus(); // Error: Object is possibly 'null'
}
React.useEffect(() => {
focusEditor()
}, []);
return (
<div onClick={focusEditor}>
<Editor
ref={editor}
editorState={editorState}
onChange={editorState => setEditorState(editorState)}
/>
</div>
);
}

这应该足以重现错误,我也安装了@types/draft-js,没有其他问题。

问题是editor的类型隐式设置为React.MutableRefObject<null>这是一个具有current属性的对象,该属性保存传入的泛型参数。所以签名将类似于这样:

interface MutableRefObject<T> {
current: T | null
}

由于你传入了null,泛型参数被推断为也是null的。因此,这是editor.current应该能够持有的唯一价值。

您应该明确地告诉 TypeScript 编译器您希望将什么作为泛型参数作为泛型参数传递useRef<SomeType>()。你可以通过使用any作为泛型参数来回避这个问题,但你最好说出该对象的类型到底是什么。下面是一个示例:

import React from 'react';
interface Focusable {
focus: () => void
}
const editor = React.useRef<Focusable>(null);
function focusEditor() {
if (null === editor) {
throw Error('editor is null') 
}
if (null === editor.current) {
throw Error('editor.current is null') 
}
editor.current.focus(); 
}

在 TypeScript Playground 上查看

我不确定那里的预期类型是什么,最好只使用HTMLElement甚至更具体的东西,例如HTMLTextAreaElement,而不是我创建的示例Focusable

无论如何,这可以得到改进:

React.useRef()总是返回一个对象editor是一个常量,因此不能重新分配。这意味着它永远不会null.您可以删除第一个检查。

唯一可以null的是editor.current.如果你不想抛出错误,你可以简单地做一个标准的空保护,这将满足类型检查:

if (null !== editor.current) {
editor.current.focus();
}

这可以使用 nullish 合并运算符进一步缩短,因此您最终得到:

import React from 'react';
const editor = React.useRef<HTMLElement>(null);
function focusEditor() {
editor.current?.focus();
}

在 TypeScript Playground 上查看

最新更新