簡體   English   中英

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

[英]TypeScript + useRef<X|Y>: Type X is not assignable to type Y

這個簡單的組件:

const Editable = ({multiline}: { multiline: boolean }) => {
    const ref = useRef<HTMLInputElement|HTMLTextAreaElement>(null);
    return <div>
        {multiline ? <textarea ref={ref}/> : <input ref={ref}/>}
    </div>
}

有以下打字稿錯誤:

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 ... />期望一個裁判的是需要HTMLTextAreaElement HTMLTextAreaElement包含不同的屬性HTMLInputElement ,所以HTMLTextAreaElement | HTMLInputElement HTMLTextAreaElement | HTMLInputElement不能被分配到節點之一 類型斷言在這里完全沒問題。 優點:我們被迫以類型安全的方式縮小ref 缺點:類型斷言有點冗長。

解決方案 2:ref 的交集類型

const ref = useRef<HTMLInputElement & HTMLTextAreaElement>(null);
return (
    <div>
        {multiline ? <textarea ref={ref } /> :
            <input ref={ref} />}
    </div>
)

這是有效的,因為HTMLInputElementHTMLTextAreaElement沒有沖突的屬性類型(否則會導致never )。 優點:更緊湊的代碼。 缺點:確保之前縮小元素。 例如,您可能能夠為導致運行時錯誤的HTMLInputElement調用以下代碼:

ref.current && ref.current.cols // input does not have cols

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM