我有类似的问题,使用 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 上查看