我使用带有React和Typescript的Draft.js与此thread存在类似的问题。使用与他们的文档示例相同的代码,在Object is possibly 'null'
函数中出现focusEditor
错误。即使当我检查空引用时,它仍然存在(就像上面引用的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
应该能够保留的唯一值。
您应该通过将其传递为useRef<SomeType>()
来明确告知TypeScript编译器您希望将其作为通用参数。您可以通过以某些类型安全为代价使用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();
}
我不确定要去的类型是什么,最好只使用HTMLElement
而不是我作为示例创建的Focusable
。
无论如何,editor
永远不会是null
,因为它是一个常数。 React.useRef
始终返回object,因此您可以删除第一张支票。因此,唯一可能是null
的是editor.current
。如果您不想引发错误,则只需执行一个沼泽标准的null保护,即可满足类型检查的要求:
if (null !== editor.current) {
editor.current.focus();
}
可以使用nullish coalescing operator进一步缩短,因此您最终会得到以下结果:
import React from 'react';
const editor = React.useRef<HTMLElement>(null);
function focusEditor() {
editor.current?.focus();
}