reactjs - 打字稿 + 使用参考: X 型不能分配给 Y 型
问题描述
这个简单的组件:
const Editable = ({multiline}: { multiline: boolean }) => {
const ref = useRef<HTMLInputElement|HTMLTextAreaElement>(null);
return <div>
{multiline ? <textarea ref={ref}/> : <input ref={ref}/>}
</div>
}
有以下 TypeScript 错误:
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.
可以使用以下行忽略错误:
const ref = useRef<any>(null);
如何useRef
使用正确的类型并且没有错误?
解决方案
解决方案 1:类型断言
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 ... />
需要一个refHTMLTextAreaElement
。HTMLTextAreaElement
包含与不同的属性 ,因此无法将超类型分配给其中一个节点。类型断言在这里非常好。优点:我们被迫以类型安全的方式缩小范围。缺点:类型断言有点冗长。 HTMLInputElement
HTMLTextAreaElement | HTMLInputElement
ref
解决方案 2:ref 的交集类型
const ref = useRef<HTMLInputElement & HTMLTextAreaElement>(null);
return (
<div>
{multiline ? <textarea ref={ref } /> :
<input ref={ref} />}
</div>
)
这有效,因为HTMLInputElement
并且HTMLTextAreaElement
没有冲突的属性类型(否则会导致never
)。优点:更紧凑的代码。缺点:确保之前缩小元素。例如,您可能能够调用以下代码来HTMLInputElement
导致运行时错误:
ref.current && ref.current.cols // input does not have cols
推荐阅读
- c# - 如何在集成测试中绕过表单发布上的防伪令牌验证
- javascript - 如何在 React Native 中的特定元素的 FlatList 中呈现函数
- java - Java - 创建一个返回偏导数的方法
- r - 当我在 R 中绘制两个“y”轴时,是否有一个 ggplot2 表格可以“反转”一个轴(geom_bar())
- shell - 将序列号作为序列添加到 UNIX 中特定位置的文件中的每一行
- xcode - 在工作区中的多个项目之间共享 xcconfig 文件
- powershell - PowerShell 立即关闭
- google-cloud-platform - 如何使用资源管理器 API 在无组织下列出我的 GCP 项目?
- sql - 使用@Query时如何修复Spring框架中的UnsatisfiedDependencyException
- django - 如何使用 Django Rest Framework 支持可选或空 FileField?