SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

JavaScriptの限界を超える!TypeScript初めの一歩

【TypeScriptの基礎を学ぶ】コードの表現力を高めよう!型ガードとジェネリクスによるデータ操作術

JavaScriptの限界を超える!TypeScript初めの一歩 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 この連載は、JavaScriptは使っているけれど、TypeScriptはまだ手を付けていない人向けのものです。あまり負担なくTypeScriptを導入して、メリットを享受することを目指します。マニアックなところには踏み込まないで、手軽にできて費用対効果が高いところを中心にあつかっていきます。第3回の今回は「TypeScriptで多様なデータに対応する方法」です。実際にありうるケースを考えながら、TypeScriptで型をあつかっていきます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 前回の記事では、さまざまなTypeScriptの型の付け方・扱い方を解説しました。

 第3回の今回は「TypeScriptで多様なデータに対応する方法」です。実際にありうるケースを考えながら、TypeScriptで型をあつかっていきます。

第1章 「型ガード」を理解して外部からのデータを扱おう

外部から読み込むデータの問題

 TypeScriptで付けた型はコンパイルすると消えます。そのため実行時のコードでは型の確認は行えません。そこで困るのが外部のデータのあつかいです。

 ファイル読み込みや通信で取得したデータは、JavaScriptのプログラムで受け取ります。TypeScriptの状態で受け取るわけではありません。そして、そのデータには型情報はなく、事前に静的解析を行えません。

 こうした問題に対処する方法が、TypeScriptには用意されています。ここではそうした方法を見ていきます。

制御フロー分析と型ガード

 TypeScriptは、変数や関数に付けた型を、代入するタイミングだけで検査しているわけではありません。より高度な処理を行っています。if文やfor文などの処理をたどり、変数に入っている型を絞り込んでいくことができます。

 TypeScriptでは、実際にコードが実行された場合の制御フローを分析して、型の可能性を追跡します。こうした機能のことを制御フロー分析と呼びます。この制御フロー分析が、どのように行われるのかを確かめましょう。

 まずは問題のあるコードの例を示します。

function getLen(p: string | undefined): number {
    let len: number = p.length;
    return len;
}

 引数pの文字列長を返す簡単なコードです。しかし、この処理には問題があります。p.lengthpのところで、'p' is possibly 'undefined'.(「p」は「未定義」である可能性があります。)というエラーが起きます。

 引数pは、p: string | undefinedと型注釈が付いています。引数pは、undefinedの可能性があるわけです。

 このコードを修正した例を示します。

function getLen(p: string | undefined): number {
    let len: number = 0;
    if (typeof p === "string") {
        len = p.length;
    }
    return len;
}

 if (typeof p === "string")のところで、変数pの型を判定しています。ここで型がstringであると絞り込んでいます。そのため、ブロック内のp.lengthはエラーになりません。

 この変数pの型の可能性が、どのように絞り込まれているのかを確かめるには、VSCode上で変数にマウスカーソルを重ねて、ポップアップを確認すると分かりやすいです。

 typeof pのところでは、変数p(parameter) p: string | undefinedと表示されます。

 if文のブロック内のp.lengthのところでは、変数p(parameter) p: stringと表示されます。型の可能性が絞り込まれているのが分かります。

 こうした型のチェックを行うコードのことを、型ガードと呼びます。

さまざまな型ガード方法

 型ガードはいくつかの方法で行えます。

 まずはtypeofです。前回登場したtypeofでは、注意すべき点があります。nullの判定です。JavaScriptでは、typeof null"object"を返します。そのため、オブジェクトとnullの可能性がある時は、さらに踏み込んだ条件分岐が必要になります。

 まずは、型ガードがなにもない場合です。

function printKeys1(p: undefined | object | null): void {
    for (let v of Object.keys(p)) {
        console.log(v);
    }
}
printKeys1({name: "Tom", age: 10});

 Object.keys()の引数はオブジェクトでなければなりません。変数pは、undefinedの可能性もnullの可能性もありますのでエラーが起きます。

 続いて、オブジェクトであるかを判定したケースです。

function printKeys2(p: undefined | object | null): void {
    if (typeof p === "object") {
        for (let v of Object.keys(p)) {
            console.log(v);
        }
    }
}
printKeys2({name: "Tom", age: 10});

 if (typeof p === "object")で型の可能性を絞り込みました。しかし、変数pは、nullの可能性が残っているのでエラーが起きます。

 次のケースです。

function printKeys3(p: undefined | object | null): void {
    if (typeof p === "object" && p !== null) {
        for (let v of Object.keys(p)) {
            console.log(v);
        }
    }
}
printKeys3({name: "Tom", age: 10});

 これでようやくエラーが起きなくなります。&& p !== nullを追加することで、nullの可能性を排除したからです。

 次の例です。

 型ガードには、特定のクラスのインスタンス化を判定するinstanceofも使えます。instanceofを使った型ガードの例を示します。

class Human {
    walk():void {}
}
class Bird {
    fly():void {}
}

function move(animal: Human | Bird) {
    if (animal instanceof Human) {
        animal.walk()
    }
    if (animal instanceof Bird) {
        animal.fly()
    }
}

 Humanのインスタンスの場合はwalkを使い、Birdのインスタンスの場合はflyを使っています。

 こうした判定は、「プロパティを持つか」を判定するin演算子でも行えます。例を示します。

function move2(animal: Human | Bird) {
    if ("walk" in animal) {
        animal.walk()
    }
    if ("fly" in animal) {
        animal.fly()
    }
}

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます
  • ・翔泳社の本が買える!
    500円分のポイントをプレゼント

メールバックナンバー

次のページ
ユーザー定義の型ガード関数

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
JavaScriptの限界を超える!TypeScript初めの一歩連載記事一覧

もっと読む

この記事の著者

柳井 政和(ヤナイ マサカズ)

クロノス・クラウン合同会社 代表社員http://crocro.com/オンラインソフトを多数公開。プログラムを書いたり、ゲームを作ったり、記事を執筆したり、マンガを描いたり、小説を書いたりしています。「めもりーくりーなー」でオンラインソフト大賞に入賞。最近は、小説家デビューして小説も書いています(『裏切りのプログラム』他)。面白いことなら何でもOKのさすらいの企画屋です。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21597 2025/09/05 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング