简体   繁体   English

打字稿 + useRef<X|Y> : X 型不能分配给 Y 型

[英]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如何与正确的类型一起使用并且没有错误?

Solution 1: Type assertion解决方案 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 ... /> 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.缺点:类型断言有点冗长。

Solution 2: Intersection type for ref解决方案 2:ref 的交集类型

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 ).这是有效的,因为HTMLInputElementHTMLTextAreaElement没有冲突的属性类型(否则会导致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

Playground 操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类型“X”不可分配给带有打字稿的“Y”类型 - Type"X' is not assignable to type "Y" with typescript 打字稿:X 类型的参数不能分配给 Y 和 X 类型的参数。X 类型不能分配给 Y 类型 - Typescript: Argument of type X is not assignable to parameter of type Y & X. Type X is not assignable to type Y 类型 X 不可分配给类型 Y - Type X is not assignable to type Y Typescript 错误:X 类型的参数不能分配给 Y 类型的参数 - Typescript error: Argument of Type X is not assignable to parameter of type Y React TypeScript:属性“ X”的类型不兼容。 类型“ Y”不可分配给类型“ Z” - React TypeScript: Types of property 'X' are incompatible. Type 'Y' is not assignable to type 'Z' TS2322-类型X不能分配给类型Y,但是Y中的所有字段都包含在X中 - TS2322 - type X is not assignable to type Y, but all fields in Y are contained in X useRef TypeScript - 不可分配给类型 LegacyRef<htmldivelement></htmldivelement> - useRef TypeScript - not assignable to type LegacyRef<HTMLDivElement> &#39;x&#39;类型的React Typescript参数不可分配给&#39;SetStateAction&#39;类型的参数<x]> &#39; - React Typescript Argument of type 'x' is not assignable to parameter of type 'SetStateAction<x]>' TypeScript - 类型“x”不可分配给类型“IntrinsicAttributes &amp; IntrinsicClassAttributes”<Class> &#39; - TypeScript - Type 'x' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Class>' React Typescript:'{ [x: number]: any; 类型的参数 }' 不可分配给类型的参数 - React Typescript: Argument of type '{ [x: number]: any; }' is not assignable to parameter of type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM