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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Generics

Genericsはパラメトリックなポリモーフィズムの形態であり、.NET やJavaなど、様々な言語に実装されています。C++のテンプレートと同等の機能を持ち合わせています。

JavaScript

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

TypeScript

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

React.js

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

Q&A

1回答

1029閲覧

TypeScriptでany[]を使わずジェネリクスでなんらかのリスト型を渡したい

eternalbeginne

総合スコア58

Generics

Genericsはパラメトリックなポリモーフィズムの形態であり、.NET やJavaなど、様々な言語に実装されています。C++のテンプレートと同等の機能を持ち合わせています。

JavaScript

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

TypeScript

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

React.js

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

0グッド

0クリップ

投稿2020/10/16 03:10

TypeScriptを今学習しています。

入力する引数の要素の型と、レスポンスの要素の型とが同じ関数を定義しており、
いまはany[]を利用しているのですが、外から型を注入できれば良いのではと思い。
typescriptのgenericsを活用して、定義できればと思っています。

サンプルコードにある、いかの3つを実現したいです。

  • someFilter()へのジェネリクス定義
  • interface Propsへのジェネリクス定義
  • interface ResPropsへのジェネリクス定義

typescript

1 2interface Props{ 3 items:any[], // ★any[]を使わず、ジェネリクスを使いT[]と定義したい 4 someKey:string 5} 6interface ResProps{ 7 filteredItems:any[] // ★any[]を使わず、ジェネリクスTを使いT[]と定義したい 8} 9export const someFilter = ({items, someKey}:Props) : ResProps => { 10 11 const filteredItems = [...items].map((item)=>{ 12 // someKeyやitemsの型に基づいたitemsの何らかの加工処理 13 if(someKey === ""){ 14 return item; 15 } 16 17 // 例としてこんなかんじ 18 if(item["name"] === undefined){ 19 return item 20 }else{ 21 item["name"] = item["name"] + "様" 22 } 23 24 if(item[someKey] === undefined){ 25 return item 26 }else{ 27 item["name"] = item["name"] + someKey 28 } 29 return item 30 }) 31 32 return { 33 filteredItems 34 } 35}

関数を利用するスクリプトはこんな感じです。

typescript

1//例1 2interface Author{ 3 id: number, 4 name: string; 5} 6 7const authorItems:Author[] = getItems("author"); // 引数に応じてなんらかのリストを取得 8const {filteredItems} = someFilter({items: authorItems, someKey:"name"}) 9//↓こうしたい 10const {filteredItems} = someFilter<Author>({items: authorItems, someKey:"name"})

typescript

1//例2 2interface Post{ 3 id: number, 4 title: string; 5} 6const postItems:Post[] = getItems("post"); 7const {filteredItems} = someFilter({items: postItems, someKey:"title"}) 8//↓こうしたい 9const {filteredItems} = someFilter<Post>({items: postItems, someKey:"title"})

typescript

1//例3 2const stringItems: string[] = ['コーラ','ソーダ']; 3const {filteredItems} = someFilter({items: stringItems, someKey:""}) 4//↓こうしたい 5const {filteredItems} = someFilter<string>({items: stringItems, someKey:""})

次のように、<T extends {}>などの定義で解決しそうな感じもしたのですが、
加工処理でエラーが発生してしまいました。

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.   No index signature with a parameter of type 'string' was found on type '{}'. TS7053: Element implicitly has an 'any' type because expression of type '"name"' can't be used to index type '{}'.   Property 'name' does not exist on type '{}'

TypeScript

1// typescirptのエラーが生じるコード 2 3interface Props<T>{ 4 items:T[], 5 someKey:string 6} 7interface ResProps<T>{ 8 filteredItems:T[] 9} 10export const someFilter = <T extends {}>({items, someKey}:Props<T>) : ResProps<T> => { 11 12 const filteredItems = [...items].map((item)=>{ 13 // ここでTypeScriptのErrorが発生します。 14 15 if(someKey === ""){ 16 return item; 17 } 18 19 // 例としてこんなかんじ 20 if(item["name"] === undefined){ 21 return item 22 }else{ 23 item["name"] = item["name"] + "様" 24 } 25 26 if(item[someKey] === undefined){ 27 return item 28 }else{ 29 item["name"] = item["name"] + someKey 30 } 31 return item 32 33 return items; 34 }) 35 36 return { 37 filteredItems 38 } 39}

アドバイスをお願いします。

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

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

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

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

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

guest

回答1

0

加工処理でエラーが発生してしまいました。

Tの型をもう少し具体的にすれば解決できます。

<T extends Record<string, string> & {name?: string}>

投稿2020/10/16 03:39

編集2020/10/16 03:42
maisumakun

総合スコア145184

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

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

maisumakun

2020/10/16 03:43 編集

すみません、読み間違えていたので書き直しました。
eternalbeginne

2020/10/17 06:32

いろいろ試してみているんですけど、解消されないですね。 質問文がわるかったのかもしれないですが、 文字列の配列でも渡せるし、ナンバーの配列でも渡せるし、あらゆる型オブジェクトの配列でもわたせる。 っていう、汎用性のある関数を作りたかったんです。 なおかつ、オブジェクトの型が渡された場合は、そのオブジェクトのあらゆるプロパティの値にそって、配列を加工したい。と。 「何でも渡せる=型safeではない」と考えるべきですかね。それであれば、any[]でいいやとわりきれるんですが。 今こんな感じで定義してあり、文字列配列、数字配列には対応できないとしました。 ``` interface Props<T> { items: T[] , someKey?: keyof T } const someFilter = <T extends {[key: string]:any}>({items, someKey}: Props<T>): ResProps<T> => { ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問