[英]TypeScript + useRef<X|Y>: Type X is not assignable to type Y
This simple component:这个简单的组件:
const Editable = ({multiline}: { multiline: boolean }) => {
const ref = useRef<HTMLInputElement|HTMLTextAreaElement>(null);
return <div>
{multiline ? <textarea ref={ref}/> : <input ref={ref}/>}
</div>
}
Have the following TypeScript errors:有以下打字稿错误:
Error:(7, 32) TS2322: Type 'RefObject<HTMLInputElement | HTMLTextAreaElement>' is not assignable to type 'string | ((instance: HTMLTextAreaElement | null) => void) | RefObject<HTMLTextAreaElement> | null | undefined'.
Type 'RefObject<HTMLInputElement | HTMLTextAreaElement>' is not assignable to type 'RefObject<HTMLTextAreaElement>'.
Type 'HTMLInputElement | HTMLTextAreaElement' is not assignable to type 'HTMLTextAreaElement'.
Type 'HTMLInputElement' is missing the following properties from type 'HTMLTextAreaElement': cols, rows, textLength, wrap
Error:(7, 53) TS2322: Type 'RefObject<HTMLInputElement | HTMLTextAreaElement>' is not assignable to type 'string | ((instance: HTMLInputElement | null) => void) | RefObject<HTMLInputElement> | null | undefined'.
Type 'RefObject<HTMLInputElement | HTMLTextAreaElement>' is not assignable to type 'RefObject<HTMLInputElement>'.
Type 'HTMLInputElement | HTMLTextAreaElement' is not assignable to type 'HTMLInputElement'.
Type 'HTMLTextAreaElement' is missing the following properties from type 'HTMLInputElement': accept, align, alt, checked, and 23 more.
The errors could be ignored using this following line:使用以下行可以忽略错误:
const ref = useRef<any>(null);
How can useRef
be used with the correct type and without errors? useRef
如何与正确的类型一起使用并且没有错误?
const ref = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
return (
<div>
{multiline ? <textarea ref={ref as React.RefObject<HTMLTextAreaElement>}/>:
<input ref={ref as React.RefObject<HTMLInputElement>} />}
</div>
)
<textarea ... />
expects a ref that takes HTMLTextAreaElement
. <textarea ... />
期望一个裁判的是需要HTMLTextAreaElement
。 HTMLTextAreaElement
contains different properties than HTMLInputElement
, so the supertype HTMLTextAreaElement | HTMLInputElement
HTMLTextAreaElement
包含不同的属性比HTMLInputElement
,所以超HTMLTextAreaElement | HTMLInputElement
HTMLTextAreaElement | HTMLInputElement
cannot be assigned to one of the nodes. HTMLTextAreaElement | HTMLInputElement
不能被分配到节点之一。 A type assertion is perfectly fine here.类型断言在这里完全没问题。 Pros: we are forced to narrow
ref
in a type-safe way.优点:我们被迫以类型安全的方式缩小
ref
。 Cons: Type assertions are a bit verbose.缺点:类型断言有点冗长。
const ref = useRef<HTMLInputElement & HTMLTextAreaElement>(null);
return (
<div>
{multiline ? <textarea ref={ref } /> :
<input ref={ref} />}
</div>
)
This works, as HTMLInputElement
and HTMLTextAreaElement
don't have conflicting property types (otherwise it would result in never
).这是有效的,因为
HTMLInputElement
和HTMLTextAreaElement
没有冲突的属性类型(否则会导致never
)。 Pros: more compact code.优点:更紧凑的代码。 Cons: Make sure to narrow the element before.
缺点:确保之前缩小元素。 Eg you might be able to invoke following code for
HTMLInputElement
leading to runtime errors:例如,您可能能够为导致运行时错误的
HTMLInputElement
调用以下代码:
ref.current && ref.current.cols // input does not have cols
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.