質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SPA(Single-page Application)

SPA(Single-page Application)は、単一のWebページのみでコンテンツの切り替えができるWebアプリケーションもしくはWebサイトです。ブラウザでのページ遷移がないため、デスクトップアプリケーションのようなUXを提供します。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

2170閲覧

【React】FunctionComponentのpropsの型をジェネリクスで定義したいです

tanana_m

総合スコア28

SPA(Single-page Application)

SPA(Single-page Application)は、単一のWebページのみでコンテンツの切り替えができるWebアプリケーションもしくはWebサイトです。ブラウザでのページ遷移がないため、デスクトップアプリケーションのようなUXを提供します。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2021/05/12 10:36

編集2021/05/12 10:56

###知りたいこと
タイトル通りなのですが、propsの型をジェネリクスで定義したいです。
やりたいこととしては以下のようなイメージです。

ts

1interface Foo { 2 foo: string; 3} 4 5// エラー 6const FCNG: React.FC<<T extends Foo>> = (props) => { 7 return <></>; 8};

propsの型について、あるinterfaceをextendsしてることを条件としたいです。

以下のコードだとエラー無しで定義できることは確認してます。

interface Foo { foo: string; } const FCOK = <T extends Foo>(props: T): React.ReactElement => { return <></> }

しかし、現在のプロジェクトでは基本ルールとしてコンポーネントはReact.FCを使用して定義することが決まっているため、ルールに沿った形で定義するやり方があれば是非教えていただきたいです。
もしそのような方法は無く前者のやり方しかないようであれば、なぜそうなるのかを教えていただければと思います。
(TypeScriptのドキュメントを読んでみたのですが、ジェネリクスを使用できるのはfunction, interface, classを定義する場合だけだから、でしょうか…?)

宜しくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/05/12 10:46

そもそも論ですが、どのような事情でそのようなジェネリック化が必要となったのでしょうか?
maisumakun

2021/05/12 11:02

interface Foo自体がジェネリックでなかったので、「foo以外のどんなpropが来ても受け取れる」コンポーネントを書きたいのかと誤解していました。
tanana_m

2021/05/12 11:06

誤解させてしまい申し訳ないです。 Fooをextendsしてるpropのみ受け取れるようにしたいと思っております。
maisumakun

2021/05/12 11:11

> Fooをextendsしてるpropのみ受け取れるようにしたいと思っております。 いえ、現状のコードでそう読めてしまう({foo: string, bar: number}のような型もT extends Fooとなる)という話です。
tanana_m

2021/05/12 11:18

ご指摘ありがとうございます。 わかりづらくて申し訳ないです。 実際の実装は以下のようになり、(importは省略) type StripeElement = | typeof AuBankAccountElement | typeof CardCvcElement | typeof CardExpiryElement | typeof CardNumberElement | typeof FpxBankElement | typeof IbanElement | typeof IdealBankElement interface StripeTextFieldProps<T extends StripeElement> extends Omit<TextFieldProps, 'onChange' | 'inputComponent' | 'inputProps'> { onChange?: React.ComponentProps<T>['onChange'] inputProps?: React.ComponentProps<T> stripeElement: T } export const StripeTextField = <T extends StripeElement>( props: StripeTextFieldProps<T> ) => { const { InputLabelProps, stripeElement, InputProps = {}, inputProps, ...other } = props return ( <TextField fullWidth InputLabelProps={{ ...InputLabelProps, shrink: true, }} InputProps={{ ...InputProps, inputProps: { ...inputProps, ...InputProps.inputProps, component: stripeElement, }, inputComponent: StripeInput, }} {...(other as any)} /> ) } type StripeElementをextendsしているのであればpropとして受けてOKとなります。
guest

回答1

0

ベストアンサー

TypeScriptのドキュメントを読んでみたのですが、ジェネリクスを使用できるのはfunction, interface, classを定義する場合だけだから、でしょうか…?

そうですね。const foo: Generics<T>のような、型パラメータの残った型の変数は宣言できませんので、ジェネリクスが有効なままで関数を変数に代入したい場合、「型を宣言しないで関数リテラル側にジェネリクスを書く」もしくは「interfaceの関数シグネチャにジェネリクスを入れて、それを変数の型に指定する」といった手段しかありません。

投稿2021/05/12 11:25

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanana_m

2021/05/12 11:49

ご教示いただき、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問