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

TypeScriptにてユニオン型の型ガードを整理したい

Posted at

型ガードとは

  • 型絞り込みのために使う論理チェックのこと

ユニオン型とは

  • ある値の取り得る型の数を、2つ以上に拡大する
let hoge: string | number

ユニオン型の型ガードを整理する

  • 複数の型をもつユニオン型などの場合はどのように型ガードするといいのかを整理したい

ユニオン型だと型安全ではないと言われる

  • TypeScriptの型システムではユニオン型などの複数の型を取り得る場合に、
    そのプロパティにアクセスするとどちらかの型がくるかわからないため型安全ではないと判断される
// hoge: string | number
let hoge = Math.random() > 0.5 ? 'John' : 40;

// 引数にstringかまたはnumberのどちらが来るかわからない
fugafuga(hoge)

値を割り当てる

  • TypeScriptは変数に値が割り当てられたら、その変数が何の型なのかを理解してくれます
  • 値を割り当ててしまえば、その変数はstring型なんだとTypeScriptが理解してくれる
let hoge: string | number

hoge = "hoge"

hoge.toUpperCase()

typeof演算子を使用する

  • string型やnumber型などを絞り込みたい場合はtypeofなどを使用する
  • tyoeof はその値の型を文字列で返してくれます
  • 注意点としてはその値の型がnullだった場合に"object"として返ってくる
// hoge: string | number
let hoge = Math.random() > 0.5 ? 'John' : 40;

const fugafuga = (param: string | number) => {
    if (typeof hoge === 'string') {
        console.log(hoge.toUpperCase())
    }
}

typeof演算子を使用して、値がnullの場合

  • nullかどうかは別で判定条件を設ける必要がある
const isObject = (value) => {
  return value !== null && typeof value === "object";
}

in演算子を使用する

  • オブジェクトのユニオン型だとどのように型ガードを行えばいいか?

  • in演算子でオブジェクトのプロパティが含まれているかどうかをチェックする


type PoemWithPages = {
    name: string
    pages: number
}

type PoemWithRhymes = {
    name: string
    rhymes: boolean
}

type Poem = PoemWithPages | PoemWithRhymes

const poem: Poem = Math.random() > 0.5 ? { name: "Hogehoge", pages: 7 } : { name: "Fugafuga", rhymes: true }
if ("pages" in poem) {
    console.log(poem.pages)
} else {
    console.log(poem.rhymes)
}

両方のオブジェクトに共通しているプロパティだと絞り込めない

// 両方のオブジェクトに共通しているプロパティだと絞り込めない
if ("name" in poem) {
    console.log(poem.pages)
} else {
    console.log(poem.rhymes)
}

タグ付きユニオン型にする

タグのプロパティを設けてそのプロパティでどのオブジェクトかを判別できるようにする


type PoemWithPages = {
    name: string
    pages: number
    type: 'pages'
}

type PoemWithRhymes = {
    name: string
    rhymes: boolean
    type: 'rhymes'
}

type Poem = PoemWithPages | PoemWithRhymes

const poem: Poem = Math.random() > 0.5 ? { name: "Hogehoge", pages: 7, type: 'pages' } : { name: "Fugafuga", rhymes: true, type: 'rhymes' }
if (poem.type === 'pages') {
    console.log(poem.pages)
} else {
    console.log(poem.rhymes)
}

おわりに

今回はユニオン型の型ガードについて学習していて、それらを整理したかった

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?