7
1

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 3 years have passed since last update.

ここが好きだよTypeScript

Last updated at Posted at 2020-12-17

この記事はWanoグループアドベントカレンダー2020の17日目の記事となります。

こんにちは。アルファアーキテクト株式会社でエンジニアをやっています、stk0724です。(今月Wanoから転籍しました)

ここ一年ほどReact + TypeScriptで広告配信設定管理画面のリニューアルプロジェクトに携わっていたため、TypeScriptの好きなところを書いてみようと思います。(ちなみにバックエンドおじさんなので、フロントエンド専業の人から見るとおかしなことが書いてあるかもしれない。。。

交差型 (Intersection Type)

日本語でいうと、「XかつY」みたいなのを実現する仕組みですね。

コードで書くと以下のようなの。

type Hoge = {
  hoge: string
}

type Fuga = {
  fuga: string
}

type HogeFuga = Hoge & Fuga

上記の場合、HogeFugaはメンバーとして、hoge, fugaを持つ型となります。

どういうときに使うと嬉しいのか?

メンバーが少しづつ異なる型を多数定義するときに使いました。

以下のような感じです。

type BaseState = {
  isLoading: boolean
  errorMessage: string
}

type VideoState = BaseState & {
  videoData?: VideoData
}

type ThumbnailState = BaseState & {
  thumbnailData?: ThumbnailData
}

似たりよったりのフォームがたくさんあるときに、共通項目をベースとなる型で定義しておいて、それを拡張するイメージです。

リテラル型 (とユニオン型)

リテラル型は、JavaScriptのプリミティブな値を型として指定できるというものです。

例えば以下のようなやつ

const name: "stk0724" = "stk0724" //"stk0724"以外代入できない

上記の場合、コメントのとおり型に指定した文字列以外を代入できないため、使い所がありません。
しかし、ユニオン型と組み合わせると素敵なやつに様変わりします。

type WanoGroup = "Wano" | "EDO CODE" | "アルファアーキテクト" | "TuneCore Japan"
const company1: WanoGroup = "Wano"
const company2: WanoGroup = "EDO CODE"

function sayWanoGroup(company: WanoGroup) {
  console.log(company)
}

sayWanoGroup(company1)
sayWanoGroup(company2)
sayWanoGroup("アルファアーキテクト") //IDEなどで補完がきく
sayWanoGroup("サルファアーキテクト") //コンパイルエラー

ユニオン型は「XもしくはY」を表現する型です。
リテラル型とユニオン型を組み合わせると、特定の文字列のみを受け付ける型、特定の数値のみを受け付ける型などを表現することができます。

上記の例ですと、Wanoグループの社名のみを受け付けるWanoGroup型を定義しています。
そして、sayWanoGroup関数は引数にWanoGroupをとるので、条件を満たさない文字列を引数に指定するとコンパイルエラーになります。

どういうときに使うと嬉しいのか?

関数の引数にプリミティブ値をとりたいけど、特定の値のみに絞りたい場合などですかね。
あとは単純にENUMの代わりに使うとか。

Mapped Types

複雑な機能なので、説明は公式ドキュメントなどを参照してくだされ。。。

早い話が、既存の型を拡張して動的に型を定義する機能です。

type WanoGroupEmployeeCounts = {[P in WanoGroup]: number;}

const data: WanoGroupEmployeeCounts = {
  "wano": 1,
  "EDO CODE": 2,
  "アルファアーキテクト": 3,
  "TuneCore Japan": 4
}

上記の場合、WanoGroupEmployeeCountsは、WanoGroupのメンバをキー、値の型がnumberとなるオブジェクトを表現する型となります。

どういうときに使うとうれしいのか

openapi-generator-cliで出力したモデルを拡張するときに使いました。
openapi-generator-cliで出力したモデルはinterfaceになっており、交差型でそのまま拡張することができなかったためです。

interface Hoge {
  frequency: number
  price: number
}

type HogeExtended = {[P in keyof Hoge]: Hoge[P];} & {
  frequencyString: string
  priceString: string
}

上記の場合、まずHogeのメンバーをkeyofで列挙してキーとし、値の型はHogeの対応するキーの値の型をそのままもってきています。
早い話が、interfaceをtypeに変換しています。そして、交差型を使ってメンバーを拡張しています。

終わり

だいたいTypeScriptの型システムの話ですね。

TypeScriptはいいんですが、バックエンドおじさんがAPI書きながら片手間でReact書くのは結構大変でした。(そしてまだリリースできていません。。。)

アルファアーキテクトではエンジニアを絶賛募集中です

参考リンク

7
1
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
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?