React 19における ref as prop のTypeScript対応
React 19で導入された新しいref as prop機能により、forwardRef
を使わずコンポーネントで直接ref
プロパティを受け取れるようになりました。しかし公式ドキュメントのTypeScript対応が不足しているため、適切な型付け方法に混乱が生じています。
問題の本質
- React 19で
ref
が通常のプロップスとして扱えるようになった - 公式サンプルがJavaScriptのみで型定義が不明
ref
プロパティにどんなTypeScript型を指定すべきか不透明- 既存の
React.RefObject
では型エラーが発生するケース
✅ 推奨解決策: Ref<T>
型の使用
ref
プロパティには**React.Ref<T>
型**を使用します。DOM要素またはコンポーネントインスタンスを適切に型付けできます。
tsx
import type { Ref } from 'react';
type Props = {
placeholder?: string;
ref?: Ref<HTMLInputElement>; // Ref型+オプショナル指定
};
function MyInput({ placeholder, ref }: Props) {
return <input placeholder={placeholder} ref={ref} />;
}
tsx
function ParentComponent() {
const inputRef = useRef<HTMLInputElement>(null);
return (
<MyInput
ref={inputRef} // 正常に動作
placeholder="検索..."
/>
);
}
必須ポイント
- 常にオプショナルとして定義
ref?: Ref<T>
形式で宣言(必須ではないため) - 具体的な要素型を指定
HTMLInputElement
、HTMLDivElement
など対象要素を厳密に - 汎用型で柔軟に対応
Ref<T>
はRefObject<T> | ((instance: T) => void)
を内包
🚫 RefObject<T>
では不十分な理由
初期の回答で提案されたRefObject
では関数型ref((ref) => {}
)を扱えず型エラーが発生します。
ts
// 関数型refを受け付けないため実用性が低い
ref: React.RefObject<HTMLInputElement>;
🔧 高度なケース: カスタム要素への対応
サードパーティライブラリなど、特殊なref処理が必要な場合の実装例:
ts
import type { Ref } from 'react';
import type { LexicalEditor } from 'lexical';
type EditorProps = {
ref?: Ref<LexicalEditor>;
};
function RichTextEditor({ ref }: EditorProps) {
return (
<EditorRefPlugin
editorRef={(editorRef) => {
if (!ref) return;
// 関数型refとオブジェクト型refを両対応
typeof ref === 'function'
? ref(editorRef)
: (ref.current = editorRef);
}}
/>
);
}
💡 代替アプローチ: ComponentProps
の活用
コンポーネントのprops全体を型継承する方法も有効です。ネイティブ要素の属性をそのまま利用できる利点があります。
tsx
import { ComponentProps } from 'react';
// input要素の全てのpropsを継承(ref含む)
function MyInput(props: ComponentProps<"input">) {
return <input {...props} />;
}
// 使用例
<MyInput ref={ref} placeholder="名前を入力" />;
重要注意点
- Reactバージョン確認
React 19.0.0以上であることをpackage.json
で確認 - 型定義の更新
@types/react
を最新版に更新 - 既存コンポーネント移行時
forwardRef
とref as prop
の混在使用は非推奨 - テストの必須性
関数型ref・オブジェクト型refの両方で動作検証を実施
React 19のref as propは型安全性を保ちつつコンポーネント設計をシンプルにします。Ref<T>
の適切な使用で、型エラーなしに新機能を活用可能です。