SHOEISHA iD

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

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

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

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

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

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

ユーザー定義の型ガード関数

 型ガードを全てのコードに細かく書いていると非常に冗長になります。型ガードは関数として定義できます。型ガードを関数化するには、関数の戻り値の記述を少し変えます。

 例を示します。

class Human {
    punch(): void { console.log("Punch!") }
}
class Mage extends Human {
    cast(): void { console.log("Cast Magick!") }
}


function isMage(chara: Human): chara is Mage {
    return chara instanceof Mage;
}
function attack(chara: Human) {
    if (isMage(chara)) {
        chara.cast();
    } else {
        chara.punch();
    }
}


let chara = new Human();
let mage = new Mage();
attack(chara);
attack(mage);

 isMage関数の戻り値の注釈chara is Mageが型ガード関数に必要な記述です。

 attack関数では、isMage関数を使って型ガードを行っています。

any型とunknown型

 any型は、あらゆる値を許容する型です。何も型を設定しないのと同義です。TypeScriptにしたけど、とりあえず何か型を書いておくといったときに使います。

 unknown型も何でもありですが、any型よりも安全な型です。unknown型の変数は、他の型の変数に代入できません。また、メソッドが使えません。型ガードで型を絞り込んだあとに実際の処理を行っていきます。

let p1: unknown = 100;
let p2: unknown = p1;       // これは大丈夫
let p3: number = p1;        // これはエラー

console.log(p1.toFixed(0)); // これはエラー

if (typeof p1 === "number") {
    console.log(p1.toFixed(0)); // これは大丈夫
}

読み込んだJSONデータに対処してみる

 それでは、外部からデータを読み込んだと想定して、JSON文字列から作成したオブジェクトに対して処理を行ってみましょう。

 仮の文字列データ'{name: "Tom", age: 10}'を利用した処理を書きます。

type User = {
    name: string;
    age: number;
};

function isUser(obj: any): obj is User {
    return (
        typeof obj === 'object' && obj !== null &&
        typeof obj.name === 'string' &&
        typeof obj.age === 'number'
    );
}

function dumpUser(obj: any) {
    if (isUser(obj)) {
        let len: number = obj.name.length;
        let fix: string = obj.age.toFixed(0);
        console.log(`${obj.name}: len ${len}`);
        console.log(`${obj.age}: fixed ${fix}`);
    }
}


let json = '{name: "Tom", age: 10}';
dumpUser(JSON.parse(json))

 Userという型と、isUserという型ガード関数を用意して、dumpUser関数内の処理を書いています。

 if (isUser(obj))のブロックの中で、nameにマウスカーソルを重ねてください。(property) name: stringと表示されます。nameが文字列であると絞り込まれています。同様にageにマウスカーソルを重ねると(property) age: numberと表示されます。ageが数値であると絞り込まれています。

 このように型ガードを使うことで、外部から読み込んだデータを、TypeScriptの静的解析で扱うことができるようになります。

次のページ
第2章 コードの表現力を高める応用的な型

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

JavaScriptの限界を超える!TypeScript初めの一歩連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/21597 2025/09/05 11:00

イベント

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

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

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

メールバックナンバー