LoginSignup
0
0
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

【TypeScript初心者向け】ユニオン型に共通のプロパティを追加する方法

Last updated at Posted at 2024-06-10

はじめに

私は、実務経験9ヶ月のフロントエンドエンジニアです。
React/TypeScriptを使って開発しています👩‍💻

実務で既存の型から新しく型を合成するときに、書き方を迷った事例があったので共有します。
私が勘違いしていたポイントも載せるので、参考にしていただけると嬉しいです。

  • 対象読者: TypeScript初心者

目的

以下のようにユニオン型で定義されたUnionType型の各型(A型B型C型)に、共通のプロパティid: numberを追加した新しい型を作ります。

interface A {
  a: string
}
interface B {
  b: string
}
interface C {
  c: string
}

type UnionType = A | B | C

例えばA型id: numberを追加した場合、{a: 'odendayoko',id: 123}のような値を代入できます。これをA型B型C型すべてに展開させて、共通のプロパティidを追加した新しい型を作りたいです。

結論

先に、どのように定義したら目的の型を得られるのか、結論を書きます。

  • ユニオン型インターセクション型を組み合わせることで、ユニオン型の各要素に共通のプロパティを追加した新しい型を合成できる
  • このとき分配法則が適用されるので、以下のように書くことができる
type CombinedType = UnionType & {
  id: number
}

文法のおさらい

今回使用するユニオン型とインターセクション型を簡単にまとめます。

ユニオン型

  • 複数の型のうち、いずれかを取ることができる型
  • 2つ以上の型を|で繋げて書く

インターセクション型

  • 複数の型のすべてを満たす型
  • 2つ以上の型を&で繋げて書く

詳しくは以下のサイトをご覧ください。

実装

インターセクション型を使うことで、ユニオン型の各要素に共通のプロパティを追加した新しい型を作ることができます。
このとき、インターセクション型には分配法則が適用されるため、以下のように書けます。

type CombinedType = UnionType & {
  id: number
}

このCombinedType型は、UnionType型A型B型C型のいずれか)に共通のプロパティidを追加したものです。

わかりやすくするために追加したい共通プロパティを持つD型を作り、書き換えてみます。

// 追加したい共通プロパティを持つ型
interface D {
  id: number
}

type CombinedType = (A | B | C) & D;

// 分配法則で展開
type CombinedType = A & D | B & D | C & D

分配法則で()を外すように展開してみると、どのような型が作られるのか、イメージしやすいのではないでしょうか?
どちらも同じ意味ですが、前者の方がすっきりしていて見やすいですね👍

合成したCombinedType型を使うと、以下のような値を代入することができます。

const example1: CombinedType = { a: "odendayoko", id: 123 }; 
const example2: CombinedType = { b: "odeko", id: 456 }; 
const example3: CombinedType = { c: "odenkamone", id: 789 }; 

余談

すぐには、このような書き方ができることを理解できませんでした。その理由として、2つ勘違いしていたことがあります。

  • インターセクション型はオブジェクト型同士でしか使えないと思っていた
  • インターセクション型は型の足し算だと思っていた

インターセクション型はオブジェクト型同士でしか使えないと思っていた

型に型を追加するときは、インターセクション型を使うことは理解していたし、実務でもかなりの頻度で使っています。

しかし、これまでインターセクション型を使う時は、以下のようにオブジェクト型 & オブジェクト型の形式で定義することがほとんどでした。

interface E {
  name: string
}
interface F {
  id: string
}

type User = E & F

このとき、User型E型とF型のどちらも満たす型という意味になります。
よってUser型には{name: 'おでこ。', id: '@odendayoko'}のような値を代入できます。

この型合成はオブジェクト型同士でしか使えないと思っていたので、今回のようにユニオン型にオブジェクト型を追加する場合には使えないと勘違いしていました。

インターセクション型はオブジェクト型だけでなく、他の型とも組み合わせることができることを学びました。

インターセクション型は型の足し算だと思っていた

私は勝手に、インターセクション型は型の足し算だと思っていました(記号が&で足し算ぽいですし…😂)。
上記の例で言うとUser型を合成するとき、E型F型を足していると思い込んでいました。

足し算だと勘違いしていたので、分配法則が適用できることに気がつきませんでした。実際は、インターセクション型は名前の通り、積集合なので掛け算のような動作をします。したがって、共通項を括り出すことができます。

この勘違いについては、こちらの記事がとてもわかりやすく解説してくださっていたのでスッキリしました✨

終わりに

普段から使っている文法でも、少しいつもと違う応用ポイントがあると迷ってしまいますね😭
自分が迷ったところを言葉で説明できると、理解力が深まって良いと思いました✨

Xで日々の業務や日常を発信しています!
よろしければフォローをお願いします🍢

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