【TypeScript】短絡評価の方法10選! – Japanシーモア

【TypeScript】短絡評価の方法10選!

TypeScriptのロゴと、短絡評価に関連するイラストTypeScript
この記事は約21分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

TypeScriptは、JavaScriptに静的な型を付加した言語として、多くの開発者から高く評価されています。

今回の記事では、TypeScriptの特徴の一つである「短絡評価」に焦点を当て、初心者でも理解しやすい方法で、その使い方や活用法、注意点などを紹介します。

短絡評価は、コードを短くし、より効率的にプログラムを実行するための技法の一つです。

この記事を通じて、あなたのTypeScriptのスキルがさらに向上することを期待しています。

●TypeScriptの短絡評価とは

TypeScriptにおける短絡評価は、プログラムの動作を効率的にするための手法の1つです。

これは、特定の条件が満たされた時点で、以降の評価を省略するものであり、これにより計算量が削減されるとともに、コードの可読性も向上します。

短絡評価は、主に論理演算子&&(AND)、||(OR)を使用して行われます。

この技術は、JavaScriptや他の多くのプログラム言語にも存在しますが、TypeScriptでは型の安全性と組み合わせて利用することで、より強力なプログラムを作成することが可能になります。

○短絡評価の基本理念

短絡評価は、次の2つの主要な原則に基づいています。

  1. &&(AND)演算子:左辺がfalseの場合、右辺は評価されません。
  2. ||(OR)演算子:左辺がtrueの場合、右辺は評価されません。

これは、&&の場合、左辺がfalseであれば、全体の結果は必ずfalseとなるため、右辺の評価は不要となるからです。

同様に、||の場合、左辺がtrueであれば、全体の結果は必ずtrueとなるため、右辺の評価は不要となります。

例として考えると、次のようなコードがあります。

const data = null;
const result = data && data.length;

このコードでは、datanullのため、data.lengthの評価は行われず、resultnullとなります。

また、次のようなコードが考えられます。

const value = "sample";
const message = value || "デフォルトのメッセージ";

この例では、valueが空文字列でなければ、messagevalueの値となり、そうでなければ、右辺の”デフォルトのメッセージ”が代入されます。

しかし、valueが”sample”という文字列であるため、右辺の評価は行われず、messageは”sample”となります。

●短絡評価の使い方

TypeScriptではJavaScriptの基本的な構文と同様に、短絡評価を行うことができます。

短絡評価は、特定の条件を満たすときだけ次の評価や命令を実行する技法で、特に複雑なロジックや条件分岐を効率的に処理する際に役立ちます。

○サンプルコード1:ANDの短絡評価

このコードではAND演算子(&&)を使った短絡評価を紹介しています。

この例では変数isValidtrueの場合にのみ、printMessage関数が実行されます。

let isValid = true;

function printMessage() {
  console.log("短絡評価により、このメッセージが表示されました。");
}

isValid && printMessage();

上記のコードでは、isValidtrueであれば、&&の右側にあるprintMessage関数が実行される仕組みとなっています。

したがって、printMessage関数内のconsole.logが実行され、コンソールに”短絡評価により、このメッセージが表示されました。”という文字列が出力されます。

○サンプルコード2:ORの短絡評価

次に、OR演算子(||)を利用した短絡評価について紹介します。

このコードでは、変数userNameが空文字である場合、defaultNameが代入される例を表しています。

let userName = "";
const defaultName = "ゲスト";

userName = userName || defaultName;
console.log(userName);

こちらの例では、最初のuserNameが空文字のため、OR演算子の右側にあるdefaultNameuserNameに代入されます。

そのため、コンソールには”ゲスト”と表示されることになります。

○サンプルコード3:NULL合体演算子

TypeScriptでは、変数がnullまたはundefinedの場合に、デフォルトの値を設定するための特別な演算子としてNULL合体演算子(??)が用意されています。

このコードでは〇〇を使って〇〇をするコードを表しています。

この例では変数ageundefinedの場合、20が代入される仕組みを表しています。

let age: number | undefined = undefined;
const defaultAge = 20;

age = age ?? defaultAge;
console.log(age);

上記のコードを実行すると、ageundefinedが設定されているため、NULL合体演算子を利用してdefaultAgeの値が代入されることになります。

そのため、コンソールには20という数字が出力されます。

○サンプルコード4:条件付きチェーン

TypeScriptにおける短絡評価は、非常に便利であり、日々のプログラミング作業を劇的に効率化してくれます。

特に、短絡評価の中でも、条件付きチェーンは、深くネストされたオブジェクトや配列を取り扱う際の助けとなります。

このコードでは、条件付きチェーンを使って、深くネストされたオブジェクトのプロパティを安全に取得する方法を表しています。

この例では、オブジェクトの中にあるさらなるオブジェクトのプロパティを取得し、存在しない場合にはundefinedを返すことを目指しています。

type User = {
    info?: {
        name?: {
            first?: string;
            last?: string;
        };
    };
}

const user: User = {
    info: {
        name: {
            first: "Taro",
            last: "Yamada"
        }
    }
};

// 通常のプロパティ取得
const firstName1 = user && user.info && user.info.name && user.info.name.first;

// 条件付きチェーンを使ったプロパティ取得
const firstName2 = user?.info?.name?.first;

上記のサンプルコードでは、Userという型が定義されており、その中にinfoというオブジェクトがあり、さらにその中にnameというオブジェクトがネストされています。

firstName1を取得するためのコードは、一般的な方法で各プロパティの存在チェックを行っていますが、firstName2の取得では、条件付きチェーンを使うことでコードが大幅にシンプルになっています。

これを実行すると、firstName2には”Taro”という文字列が代入されることになります。

しかし、もしinfonameなどのプロパティが存在しなければ、undefinedが代入されるので安全です。

○サンプルコード5:関数のデフォルト引数と短絡評価

TypeScriptでのプログラミングにおいて、関数の引数にデフォルト値を設定する際に、短絡評価が一役買っています。

特に、関数に渡される引数がundefinednullの場合にデフォルト値を適用するといった場面でその有用性が発揮されます。

このコードでは関数のデフォルト引数に短絡評価を活用して、指定された引数がundefinedの場合のみデフォルト値を設定する方法を表しています。

この例では、greet関数を定義し、nameという引数を取ります。

このname引数に何も渡されなかった場合、デフォルトで"ゲスト"という文字列を使用しています。

function greet(name?: string) {
    let greetingName = name || "ゲスト";
    console.log(`こんにちは、${greetingName}さん!`);
}

greet(); // こんにちは、ゲストさん!
greet("山田"); // こんにちは、山田さん!

このコードを実行すると、第一のgreet関数の呼び出しでは何も引数が渡されていないので、デフォルトの"ゲスト"が使用されます。

しかし、次に"山田"という文字列を引数として渡した際には、この指定された引数が出力されます。

この方法の良い点は、関数の引数がundefinedであるかどうかを簡単にチェックできることです。

しかしながら、この方法で0や空文字列""を引数として渡すと、これらもfalsyとして評価されるため、不意にデフォルト値が適用される場面もあります。

そのため、利用する際には注意が必要です。

応用として、関数の引数にオブジェクトを取る場合、特定のプロパティの存在をチェックしてデフォルト値を設定するといった使い方も可能です。

interface UserInfo {
    name?: string;
    age?: number;
}

function displayInfo(user: UserInfo) {
    let userName = user.name || "不明";
    let userAge = user.age || "不明";
    console.log(`名前: ${userName}, 年齢: ${userAge}`);
}

displayInfo({}); // 名前: 不明, 年齢: 不明
displayInfo({name: "鈴木", age: 25}); // 名前: 鈴木, 年齢: 25

このコードを実行すると、第一のdisplayInfo関数の呼び出しではオブジェクトに何もプロパティが設定されていないので、デフォルトの"不明"が使用されます。

しかし、次にnameageを持つオブジェクトを渡すと、これらの値がそのまま使用されます。

○サンプルコード6:オブジェクトのプロパティ存在チェック

TypeScriptのプログラムを書く際、オブジェクトに特定のプロパティが存在するかどうかを確認することはよくあります。

オブジェクトのプロパティ存在チェックを簡潔に行うために、短絡評価を利用する手法を紹介します。

このコードでは、userというオブジェクトにnameプロパティが存在するかを確認し、存在する場合はそのプロパティの値を、存在しない場合はデフォルトの値として"ゲスト"を返す例を紹介しています。

この例では、短絡評価を活用してコードをシンプルに保っています。

// サンプルのuserオブジェクト
const user = {
    id: 123,
    name: "太郎"
};

// nameプロパティの存在チェックとデフォルト値の設定
const userName = user.name || "ゲスト";
console.log(userName); // 出力: 太郎

このコードを実行すると、太郎がコンソールに出力されます。

なぜなら、userオブジェクトにはnameプロパティが存在するからです。

もし、userオブジェクトが以下のようにnameプロパティを持っていない場合、

const anotherUser = {
    id: 456
};

const anotherUserName = anotherUser.name || "ゲスト";
console.log(anotherUserName); // 出力: ゲスト

nameプロパティが存在しないため、ゲストがコンソールに出力されます。

注意点として、短絡評価を使用するときは、プロパティの値がfalsyな値(0, "", null, undefined, NaN, false)である場合にもデフォルト値が使用される点に気を付ける必要があります。

例として、もしuserオブジェクトのnameプロパティが空文字の場合、

const thirdUser = {
    id: 789,
    name: ""
};

const thirdUserName = thirdUser.name || "ゲスト";
console.log(thirdUserName); // 出力: ゲスト

nameプロパティが空文字というfalsyな値であるため、短絡評価の結果としてゲストがコンソールに出力されます。

このような挙動を意図していない場合は、適切なチェック方法を選択することが必要です。

○サンプルコード7:配列の要素存在チェック

TypeScriptでプログラミングを行う際、配列内に特定の要素が存在するかどうかを確認するケースは多々あります。

この部分でも短絡評価は大変役立ちます。

では、配列の要素存在チェックにおける短絡評価の活用方法を見ていきましょう。

このコードでは、Array.prototype.includesメソッドを使って配列内に特定の要素が存在するかどうかを調べるコードを表しています。

この例では、数字の配列を定義し、その中に特定の数字が存在するかをチェックしています。

const numbers: number[] = [1, 2, 3, 4, 5];

// 3が配列内に存在するかどうかをチェック
const isThreeExists = numbers.includes(3) && "3は配列内に存在します。";
console.log(isThreeExists); // 3は配列内に存在します。

// 7が配列内に存在するかどうかをチェック
const isSevenExists = numbers.includes(7) && "7は配列内に存在します。";
console.log(isSevenExists); // false

上記の例では、配列numbersに3が存在するかどうかをチェックしています。

numbers.includes(3)の評価結果がtrueの場合、短絡評価により後の文字列が出力されます。

逆に7が存在するかどうかのチェックの場合、numbers.includes(7)がfalseを返すため、後ろの文字列は評価されず、結果としてfalseが出力されます。

注意点として、この方法は存在チェックに特化しています。存在しない場合のメッセージを表示するなどのカスタマイズを行いたい場合は、三項演算子を利用するとより柔軟に対応できます。

const messageForThree = numbers.includes(3) ? "3は配列内に存在します。" : "3は配列内に存在しません。";
console.log(messageForThree); // 3は配列内に存在します。

const messageForSeven = numbers.includes(7) ? "7は配列内に存在します。" : "7は配列内に存在しません。";
console.log(messageForSeven); // 7は配列内に存在しません。

このように三項演算子を使用することで、存在する場合と存在しない場合の両方で異なるメッセージを出力することができます。

短絡評価と三項演算子を適切に組み合わせることで、さまざまなシチュエーションに応じて効率的にコードを書くことが可能となります。

●短絡評価の応用例

TypeScriptの短絡評価は、基本的な使い方だけでなく、さまざまな場面での応用が可能です。

ここでは、特に日常のコーディングで役立つ応用例をいくつか取り上げ、具体的なコードと共に詳しく解説します。

これを機に、TypeScriptでの開発スピードアップや、よりシンプルで読みやすいコードを書くヒントを得てください。

○サンプルコード8:フィルタリング機能

このコードでは、配列の要素をフィルタリングする際に短絡評価を活用する方法を表しています。

この例では、配列内の偽として評価される要素(nullやundefined、0など)を短絡評価を用いて取り除く方法を実践しています。

// 配列に含まれるfalsyな要素を取り除く
const array = [0, 1, null, 2, "", 3, undefined];
const filteredArray = array.filter(item => item || item === 0);
console.log(filteredArray); // [0, 1, 2, 3]

コメントで解説すると、上記のコードは、arrayという配列からfalsyな要素を取り除くものです。

filterメソッドを使い、その中で短絡評価の力を借りて、0を除くfalsyな要素を削除しています。

結果として、新しい配列filteredArrayには、0, 1, 2, 3のみが残されます。

このように、短絡評価を用いることで、簡潔に配列の要素をフィルタリングすることができます。

特に、大量のデータを扱う際や、外部から取得したデータに不要な値が混ざっている場合などに、このテクニックは非常に役立ちます。

応用として、特定の条件を満たす要素だけを取得する場面でも短絡評価は有効です。

例えば、特定の文字列を含む要素だけを取り出したいときや、ある範囲の数値のみを抽出したい場合など、短絡評価と組み合わせることで、より柔軟なフィルタリングが可能になります。

このフィルタリングのコードの結果は、上記の通り、配列からfalsyな要素を綺麗に取り除くことができるのが確認できます。

これにより、データのクリーンアップや、前処理としての役割を果たすことができます。

○サンプルコード9:初期値設定のショートカット

TypeScriptにおいて、変数の初期値を設定する際に短絡評価を利用するテクニックは非常に効率的です。

短絡評価は、特定の条件下でのみ特定の操作を実行することができるため、変数がundefinedやnullの場合にデフォルトの値を設定するのに適しています。

下記のコードは、短絡評価を使用して変数の初期値を設定する基本的な方法を表しています。

この例では、変数nameがundefinedやnullの場合にのみ、デフォルトの値"未知"を設定しています。

let inputName: string | undefined = getUserName(); // getUserNameはユーザーの名前を取得する関数と仮定
let name = inputName || "未知"; 
console.log(name);

上記のコードでは、getUserName関数がユーザーの名前を返すと仮定しています。

もしgetUserName関数がundefinedを返した場合、変数nameはデフォルトの値"未知"を持ちます。

例として、もしgetUserName関数がundefinedを返す場合、コンソールには未知と表示されるでしょう。

さらに、短絡評価を利用して、より複雑な条件を持つ初期値を設定することもできます。

例えば、ユーザーからの入力が空文字列の場合や特定の文字数を超える場合に、デフォルトのメッセージを設定することも可能です。

このような短絡評価のテクニックを理解し、適切に活用することで、TypeScriptのコードの効率と可読性を高めることができます。

特に、変数の初期値設定や関数のデフォルト引数の設定など、さまざまな場面で短絡評価を活用することが推奨されます。

○サンプルコード10:関数呼び出しのコンディショナル実行

関数を呼び出すとき、特定の条件下でのみその関数を実行したい場面が多々あります。

ここでは、TypeScriptで短絡評価を使って関数呼び出しのコンディショナル実行を行う方法について詳しく説明します。

まず、基本的なサンプルコードから見ていきましょう。

// 関数定義
function greet(name: string) {
    console.log(`こんにちは、${name}さん!`);
}

// 条件変数
let isGreetingEnabled = true;

// 短絡評価を使った関数呼び出し
isGreetingEnabled && greet("太郎");

このコードでは、greet関数を使って指定された名前であいさつをします。

変数isGreetingEnabledは、挨拶の機能が有効化されているかどうかを判断するためのものです。

短絡評価を用いることで、isGreetingEnabledtrueの場合のみgreet関数が実行されます。

この例では、isGreetingEnabledtrueなので、コンソールに「こんにちは、太郎さん!」と表示されることが期待されます。

しかし、これだけでは十分ではありません。

実際の開発においては、さまざまな条件下で関数を実行する必要があります。

例えば、ユーザーの年齢が18歳以上の場合のみ、特定の関数を実行したい場面を考えてみましょう。

// 年齢を確認する関数
function checkAge(age: number) {
    if (age >= 18) {
        console.log("あなたは成人です。");
    } else {
        console.log("あなたは未成年です。");
    }
}

let userAge = 20; // ユーザーの年齢

// 短絡評価を使って関数を実行
userAge >= 18 && checkAge(userAge);

上記のコードでは、checkAge関数はユーザーの年齢に応じて成人か未成年かをコンソールに表示するものです。

userAgeが18歳以上の場合のみ関数を実行するように、短絡評価を活用しています。

この場合、userAgeが20歳なので、「あなたは成人です。」と表示されます。

このように、TypeScriptで短絡評価を活用することで、効率的に関数のコンディショナル実行を行うことができます。

特定の条件下でのみ処理を実行したい場合には、この手法が非常に有効です。

●注意点と対処法

TypeScriptの短絡評価は非常に便利な機能であり、多くの場面で活用されています。しかし、使い方を誤ると予期しない動作が生じることもあります。

ここでは、短絡評価を使用する上での注意点とそれに対する対処法を詳細に紹介します。

○短絡評価が予期しない動作をする場合

TypeScriptの短絡評価は、一見シンプルに思えるかもしれませんが、特定の状況では意図しない動作をすることがあります。

下記のコードを見てみましょう。

// 短絡評価の例
const data = null;
const result = data && data.value;
console.log(result); // 出力される値は?

このコードではdataという変数がnullの場合、data.valueを評価することなく、resultはundefinedとなります。

しかし、dataがfalsyな値(例: 0"")の場合、期待とは異なる動作が発生することがあります。

このような問題を避けるため、短絡評価を使用する際は、変数の型や値を正確に理解し、意図しない動作を引き起こさないよう注意することが重要です。

○型安全を保つためのテクニック

TypeScriptは、型安全性を保つための強力なツールセットを提供しています。

短絡評価を使用する際も、これらのツールを活用して型の誤りを防ぐことができます。

例として、オブジェクトのプロパティにアクセスする際の短絡評価を考えてみましょう。

type User = {
    id: number;
    name?: string;
}

const user: User = { id: 1 };

const userName = user && user.name ? user.name : "名無し";

このコードでは、ユーザーの名前が存在する場合はその名前を、存在しない場合は”名無し”という文字列をuserNameに代入します。

短絡評価と条件演算子を組み合わせることで、user.nameがundefinedやnullの場合の動作を制御しています。

このように、TypeScriptの型機能と短絡評価を組み合わせることで、より堅牢なコードを書くことができます。

●カスタマイズ方法

TypeScriptの短絡評価の機能を最大限に活用するために、さらなるカスタマイズ方法を学んでいきます。

ここでは、TypeScript独自の型システムと短絡評価を組み合わせて、さらに強力な機能を持つカスタマイズ手法を紹介します。

○カスタム型ガードと短絡評価の組み合わせ

TypeScriptには、型ガードという便利な機能が存在します。

これは、特定の条件下で変数の型が保証されることを示すためのものです。

この型ガードをカスタムで作成することで、短絡評価と組み合わせてより高度な型の安全性を持つコードを書くことができます。

カスタム型ガードのサンプルコードを紹介します。

function isString(value: any): value is string {
    return typeof value === 'string';
}

const value: unknown = 'TypeScript';

if (isString(value) && value.includes('Script')) {
    console.log('文字列に"Script"が含まれています。');
}

このコードでは、isString関数を使ってvalueが文字列型であるかどうかを確認しています。

この型ガード関数はvalue is stringという戻り値の型を持っており、valueが文字列であることをTypeScriptのコンパイラに伝えています。

そのため、value.includes('Script')の部分でエラーが発生せず、安全に文字列メソッドを使用することができます。

このようなコードを実行すると、「文字列に”Script”が含まれています。」という結果がコンソールに出力されます。

このカスタム型ガードを活用することで、短絡評価を使用しながらも型の安全性を確保することができます。

まとめ

TypeScriptの短絡評価を活用することで、コードの可読性や効率性を向上させることができます。

特に、TypeScript独自の型システムと組み合わせることで、より高度なプログラミングが可能になります。

この記事で紹介した手法やカスタマイズ方法を活用して、プログラミングスキルをさらにレベルアップさせていきましょう。