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

はじめに

普段からTypeScriptを使っています。

そこで、
Union Typesで複数の型を一つの型にまとめて、型の種類によって処理を分けたい
といった場面がありました。

使えそうな方法が2つほどありましたので、紹介していきます。

そもそも何がしたかったか具体的に

こういうことがしたかったです。

interface Hoge {
  // property
}

interface Fuga {
  // property
}

type Union = Hoge | Fuga;

const hoge: Hoge = {
  // Hogeのプロパティ
};

const fuga: Fuga = {
  // Fugaのプロパティ
};

const unionList: Union[] = [hoge, fuga];

const func = (arg: Union): Union => {
  if (Hogeかどうかの判定) {
    // Hoge用の処理;
  } else if (Fugaかどうかの判定) {
    // Fuga用の処理;
  } else {
    //
  }
};

const listFunc = (args: Union[]): Union[] => {
  const funcedArgs = args.map(arg => func(arg));
  return funcedArgs;
};

後の方の関数は適当ですが、要するに、まとめた型で配列を作って、型を判定しながらそれぞれの処理を行いたい、という感じです。

では、具体的にどういう方法で型を判定したかを紹介します。

Type Guard

interface Hoge {
  type: string
  text: string
}

interface Fuga {
  type: string
  number: number
}

type Union = Hoge | Fuga

const func = (arg: Union) => {
  if(isHoge(arg)){
    // Hoge用の処理
    // isHogeでbooleanを返すとHoge型だと認識されずtextプロパティない可能性あるよと怒られる
  }else if(isFuga(arg)){
    // Fuga用の処理
  }else{
    //
  }
}

const isHoge = (arg:Union): arg is Hoge => {
  return arg.type === 'Hoge'
}

const isFuga = (arg:Union): arg is Fuga => {
  return arg.type === 'Fuga'
}

型の判定後に判定した値の型を確定させることができます。

ポイントは型を判定する関数の返り値の型です。

arg is Hogeのようにしてやることで、関数の判定がtrueになったブロックでは、Hoge型として扱われます。

ここがただのBooleanだと、Hoge型として認識してくれません。

Discriminated Unions

interface Hoge {
  type: 'Hoge'
  text: string
}

interface Fuga {
  type: 'Fuga'
  number: number
}

type Union = Hoge | Fuga

const func = (arg: Union) => {
  switch (arg.type){
    case 'Hoge':
      // Hoge用の処理
    case 'Fuga':
      // Fuga用の処理
    default:
      //
  }
}

1つ目に紹介した方に比べて、型判定のための関数定義を省くことができます。

ポイントは型定義時に、type(TypeScript公式ではkind)のような、型を識別するプロパティを持たせることです。

後はswitch文で判定できます。

TypeScript3.6から追加された機能のようです。

最後に

同じようなことをしたいと思った方の参考になれば嬉しいです!

駆け足でまとめた感じがあるので、誤りあれば教えてください。

ありがとうございました!!!

0
1
2

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