4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

mofmofAdvent Calendar 2022

Day 16

食わず嫌いを克服したい:TypeScriptで苦手なところだけかいつまんでやってみた①

Last updated at Posted at 2022-12-15

はじめに

TypeScript、難しくないですか(少なくとも私は得意ではありません)? 特に抽象度が高くなるとすぐに脳内メモリが足りなくなるので、ずっと食わず嫌いをしていたのですが...。そうこうも言ってられなくなったので(遅い)、今更ながら勉強してみることにしました。

使用テキスト

使用したのはこちらのテキスト。コードもこちらの書籍から引用しています。全てのコードには該当ページ数も書いておきます。

ジェネリクス

まずは基本的なこちら。 「型引数に何を入れるかは関数を呼び出す際に決まる」 関数を作る機能のことだそうですが、それだけでは何のことかわかりづらいですよね。。。

つまりこういうことだそうです。
下記の場合、Tがジェネリクスで、 ①一つの呼び出し内でTには同じ値が入りますが、②Tにはどんな型でも入れることができます。

const repeat = <T>(element: T, length: number): T[] => { // ここのTにはどんな型でも入る
  const result: T[] = [];                                // Tは関数の中で使ってもOK
  for(let i = 0; i < length; i++) {
    result.push(element);
  }
  return result;
}

プロを目指す人のためのTypeScript入門:p.170

型引数は

  • 引数の型
  • 返り値の型
  • 関数の中

で使うことができます。(使える範囲が広すぎて鬼門だった)
こんなふうに呼び出しの際に型注釈をつけると、上記repeat関数内のTが全て型注釈でつけた型に置き換わります。

repeat<string>('hoge', 10) // T はstring型になる
repeat<number>(1, 10)      // T はnumber型になる
repeat(0, 10)              // repeatに型引数をつけなくてもOK(number型と推測される)

...が、型注釈をつけなくてもTypeScriptが推論してつけてくれます。(ここも鬼門だった)
なんなら返り値の型が無くたって推論してくれます。(さらに鬼門だった)
スクリーンショット 2022-12-06 17.54.57.png

どおりで、ある程度適当に書いていてもうまい具合にジェネリクスが当てはまってくれるワケですね。(そして適当に書いているが故にエラーが出た時にわかりづらくなる。。。。)

参考にしたテキストによると、この機能のおかげでTypeScriptは "「好きな値で呼び出せばいい感じの返り値を返してくれる関数」として機能する" (p.172)らしいです。「混乱する!」と思ってしまった自分はTSへの愛が足りなかったようです。頑張ります。

ジェネリクスの応用

ジェネリクスって、本当に色々な使い方ができるんですよね。こちらも初学の時に一気に詰め込んだ故にわかりづらくなっていたので整理します。

複数の型引数

もちろん、型引数の複数使用も可能です。下記の例ではLRにそれぞれ好きな型を割り振れます。

const pair = <L, R>(left: L, right: R): [L, R] => [left, right]
const p = pair<string, number>("tanutanu", 10)
// この時、L...string, R...number 型となる

プロを目指す人のためのTypeScript入門:p.171 のコードを一部改変

extends

extendsなどを使って、型に一部だけ制約を付けることも可能です。下記は、{name: string}というプロパティを含むオブジェクトであればコンパイルが通ります。

const repeat = <T extends { name: string }>(element: T, length: number): T[] => {
  const result: T[] = [];
  for(let i = 0; i < length; i++) {
    result.push(element);
  }
  return result;
}

type PersonalInfo = {
  name: string;
  age: number;
  hobby: string[];
}

console.log(repeat<PersonalInfo>({
    name: "tanutanu",
    age: 10,
    hobby: ['eat', 'sleep']
  }, 3))

プロを目指す人のためのTypeScript入門:p.171 のコードを一部改変

念の為解説です。
スクリーンショット 2022-12-07 18.07.02.png

だいぶ複雑になってきましたが、丁寧に見れば読み解けそうですね:relaxed:

次回予告

ユニオン型、インターセクション型とジェネリクスを使って、さらに複雑な型を読み解けるようになろうかな。

▼この記事の続きはこちら
https://qiita.com/sazumy/private/83987f0abe773565b5c1

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?