Definitelytyped: [@ types / react] useRef returntypeがrefproptypeと衝突します

作成日 2019年05月19日  ·  12コメント  ·  ソース: DefinitelyTyped/DefinitelyTyped

  • [x] @types/16.8.17パッケージを使用しようとしましたが、問題が発生しました。
  • [x] tscの最新の安定バージョンを使用してみました。 https://www.npmjs.com/package/typescript
  • [x] StackOverflowに不適切な質問があります。 (そこで適切な質問をしてください)。
Type 'MutableRefObject<HTMLDivElement | undefined>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'MutableRefObject<HTMLDivElement | undefined>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Types of property 'current' are incompatible.
      Type 'HTMLDivElement | undefined' is not assignable to type 'HTMLDivElement | null'.
        Type 'undefined' is not assignable to type 'HTMLDivElement | null'.

最も参考になるコメント

少しすっきりした解決策は、useRef関数呼び出しでinitialValueをnullに設定することです。

const componentRef = useRef<HTMLDivElement>(null);

これにより、componentRef = HTMLDivElement | nullが保証されます。これは、 HTMLDivElement | undefinedではなく、refpropが期待しているものです。

全てのコメント12件

編集2:私の解決策を無視し、以下のものを使用してください:)

私は現在同じ問題を抱えています、あなたはたまたますでに解決策を見つけましたか?

編集:私は今これを使用しています、確かにそれほどきれいではありません、解決策:

const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>;

ここで見つかりました: https ://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment -471341041

少しすっきりした解決策は、useRef関数呼び出しでinitialValueをnullに設定することです。

const componentRef = useRef<HTMLDivElement>(null);

これにより、componentRef = HTMLDivElement | nullが保証されます。これは、 HTMLDivElement | undefinedではなく、refpropが期待しているものです。

@ shane935あなたは私の一日をサーにしました🙌🏻

undefinedRefObject<T>.currentに次のように追加する必要があるようです。

//index.ts, line 80
interface RefObject<T> {
   readonly current: T | null;
}

だからそれは読む

//index.ts, line 80
interface RefObject<T> {
   readonly current: T | null | undefined;
}

これはバグではなく、正当な入力エラーをキャッチしています。

詳細については、 https: //github.com/DefinitelyTyped/DefinitelyTyped/pull/38228#issuecomment-529749802を参照してください。

@Jessidhiaが言うように、それはバグではありません、多分あなたはこのように書くべきです。

import React, {
  forwardRef,
  ForwardRefRenderFunction,
  useImperativeHandle,
  useRef,
  PropsWithChildren,
} from "react";

interface Props {}
interface Ref {
  value: string;
  setValue: (value: string) => void;
}

const InputEmail: ForwardRefRenderFunction<Ref, PropsWithChildren<Props>> = (
  props,
  ref
) => {
  // hooks
  const inputElement = useRef<HTMLInputElement | null>(null);
  useImperativeHandle(ref, () => {
    return {
      value: inputElement.current ? inputElement.current.value : "",
      setValue: (value: string) => {
        inputElement.current && (inputElement.current.value = value);
      },
    };
  });

  // render
  return (
    <div>
      <input
        type="text"
        ref={inputElement}
        defaultValue="[email protected]"
        disabled
      />
    </div>
  );
};

const Component = forwardRef(InputEmail);

export default Component;

これですべての人の問題が解決するかどうかはわかりません。私はこの問題の専門家ではありませんが、参照として渡したもののタイプと、参照を渡したコンポーネントの実際の参照タイプを確認した後、 、インターフェイスが間違っているように見えました。

私は当初、受信コンポーネント用にそのような小道具のインターフェースを持っていました:

type TextboxProps = CustomProps & React.HTMLProps<HTMLInputElement>

私が変更したもの:

type TextboxProps = CustomProps & React.HTMLAttributes<HTMLInputElement>

その後、入力エラーは消えました。

私は自分が知っている以上のことを知っているふりをするつもりはありませんが、HTMLPropsインターフェイスとReact.forwardRef()関数型の型を調べると、RefAttributesを使用していることがわかります。。 そのすぐ上に、ClassAttributesが表示されますそのHTMLPropsを入力しますLegacyRefを定義する拡張中ですタイピングの問題を引き起こしていると私が信じているタイプ。

このプロジェクトにはuseRef()に対して3つのオーバーロードがあるようですが、3つすべてが必要ですか? useRef<T>(null)の場合は、開発者がほとんどの場合に使用するケースのようです。

    function useRef<T>(initialValue: T): MutableRefObject<T>;
    function useRef<T>(initialValue: T|null): RefObject<T>;
    function useRef<T = undefined>(): MutableRefObject<T | undefined>;
  1. 2つの可変オーバーロードの予想されるユースケースは何ですか?
  2. ユーザーが「正しい」過負荷をより簡単に見つけることができるように、これをサポートできる他の方法はありますか?

私はRefObjectを持っています:

Screen Shot 2020-08-23 at 1 06 16 PM

私はそれを小道具refとしてPanelコンポーネントに渡します:

Screen Shot 2020-08-23 at 1 06 04 PM

forwardRefで消費しようとすると、 MutableRefObjectになります:

Screen Shot 2020-08-23 at 1 06 56 PM

.currentプロパティを使用できなくなりました:

Screen Shot 2020-08-23 at 1 10 27 PM

@Jessidhia @ osf2eあなたの提案はここでは当てはまらないようです。

私が頼らなければならなかった回避策:

        if (ref && (ref as RefObject<HTMLDivElement>).current) {
              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
              (ref as RefObject<
                HTMLDivElement
              >)!.current!.style.height = `${containerHeight}px`;
            }

react-native-webを使用して、使用する必要がありました。

import {RefObject} from 'react';
// ...
const myRef = useRef() as RefObject<View>

Input要素の参照でこの問題が発生しました
だから私はuseRef<HTMLDivElement>() -> useRef<HTMLInputElement>()から切り替えました、そしてそれはうまくいきました

@joshribakoffパラメータを直接入力することもできます

export const Panel = React.forwardRef((props: PanelProps, ref: React.RefObject<HTMLDivElement>) => {

そうすれば、参照にアクセスするときに型キャストする必要がなくなります。
しかし、なぜ私たちがこれをしなければならないのか私はまだ理解していません...

このページは役に立ちましたか?
0 / 5 - 0 評価