TypeScriptにおける条件分岐のベストプラクティス

TypeScriptにおける条件分岐のベストプラクティス

この記事ではTypeScriptにおける条件分岐のベストプラクティスについて説明します。

YouTube Video

TypeScriptにおける条件分岐のベストプラクティス

型ガードを使用して型を絞り込む

TypeScriptの型システムを利用して、if文内で型ガードを使用することで、型安全性と可読性を向上させることができます。

1function processInput(input: string | number) {
2    if (typeof input === "string") {
3        console.log(`String input: ${input.toUpperCase()}`);
4    } else {
5        console.log(`Number input: ${input.toFixed(2)}`);
6    }
7}

typeofや他の型ガードを使用することで、各ブロック内のコードが型安全で文脈に適したものになります。

ネストしたif文を避ける

ネストが深いif文はコードの可読性と保守性を低下させます。代わりに、早期リターンや論理演算子、関数の抽出を活用しましょう。

悪い例:

1function checkUser(user: { age?: number; isAdmin?: boolean }) {
2    if (user.age) {
3        if (user.age > 18) {
4            if (user.isAdmin) {
5                console.log("User is an adult admin.");
6            }
7        }
8    }
9}

改善例:

1function checkUser(user: { age?: number; isAdmin?: boolean }) {
2    if (!user.age || user.age <= 18 || !user.isAdmin) {
3        return;
4    }
5    console.log("User is an adult admin.");
6}

このアプローチによりコードが平坦化され、ロジックがより分かりやすくなります。

オプショナルチェイニングを活用する

ネストしたプロパティをチェックする際には、オプショナルチェイニング(?.)を使用して不要なif条件を避けましょう。

オプショナルチェイニングを使わない場合:

1if (user && user.profile && user.profile.email) {
2    console.log(user.profile.email);
3}

オプショナルチェイニングを使用:

1if (user?.profile?.email) {
2    console.log(user.profile.email);
3}

これによりボイラープレートコードが削減され、可読性が向上します。ここで、ボイラープレートコード(boilerplate code)とは、プログラムを書く際に頻繁に繰り返し使用される、特定の目的を達成するために必要な定型的なコードのことを指します。

厳密等価演算子を使用する

TypeScriptは厳密な型付けをサポートしており、厳密等価(===)や厳密不等価(!==)を使用することで予期しない型変換を避けることができます。

悪い例:

1if (value == "123") {
2    console.log("Value is 123.");
3}

改善例:

1if (value === "123") {
2    console.log("Value is 123.");
3}

明示的な条件には列挙型やリテラル型を使用する

列挙型やリテラル型を使用することで、条件を明確にし、エラーの可能性を減らすことができます。

 1type Status = "success" | "error" | "loading";
 2
 3function displayMessage(status: Status) {
 4    if (status === "success") {
 5        console.log("Operation succeeded.");
 6    } else if (status === "error") {
 7        console.log("Operation failed.");
 8    } else {
 9        console.log("Loading...");
10    }
11}

期待される値を定義することで、TypeScriptはタイプを検出し、正確性を確保できます。

類似する条件を統合する

複数の条件が同じロジックを共有している場合は、論理演算子やswitch文を使用して統合しましょう。

悪い例:

1if (role === "admin") {
2    grantAccess();
3}
4if (role === "superadmin") {
5    grantAccess();
6}

改善例:

1if (role === "admin" || role === "superadmin") {
2    grantAccess();
3}

または、switch文を使用して複数の明確な分岐を処理します:

 1switch (role) {
 2    case "admin":
 3    case "superadmin":
 4        grantAccess();
 5        break;
 6    case "user":
 7        console.log("Limited access.");
 8        break;
 9    default:
10        console.log("No access.");
11}

条件式を複雑にしない

if文の条件式が複雑になると可読性が低下します。意味のある変数や関数に抽出しましょう。

悪い例:

1if (user.age > 18 && user.isAdmin && user.permissions.includes("write")) {
2    console.log("User can write.");
3}

改善例:

1const isAdultAdminWithWriteAccess =
2    user.age > 18 && user.isAdmin && user.permissions.includes("write");
3
4if (isAdultAdminWithWriteAccess) {
5    console.log("User can write.");
6}

条件に名前を付けることで、明確さが向上し、コードが自己文書化されます。

単純な条件には三項演算子を使用する

単純な条件の場合、三項演算子を使用するとコードが簡潔になります。

例:

1const message = isLoggedIn ? "Welcome back!" : "Please log in.";
2console.log(message);

ただし、複雑な条件に三項演算子を使用すると可読性が低下するため避けましょう。

配列やマップを使って条件分岐を置き換える

条件が単純に値のマッピングである場合、switch文や複雑なif-else文よりも、配列やマップを使うことでコードの可読性と保守性が向上します。TypeScriptでは、型情報も活かしてより安全に実装することができます。

悪い例:

 1function getDayName(day: number): string {
 2    switch (day) {
 3        case 0:
 4            return "Sunday";
 5        case 1:
 6            return "Monday";
 7        case 2:
 8            return "Tuesday";
 9        case 3:
10            return "Wednesday";
11        case 4:
12            return "Thursday";
13        case 5:
14            return "Friday";
15        case 6:
16            return "Saturday";
17        default:
18            return "Invalid day";
19    }
20}

改善例: 配列を使う

 1function getDayName(day: number): string {
 2    const days = [
 3        "Sunday",
 4        "Monday",
 5        "Tuesday",
 6        "Wednesday",
 7        "Thursday",
 8        "Friday",
 9        "Saturday"
10    ];
11    return days[day] ?? "Invalid day";
12}

改善例: Mapを使う

 1function getDayName(day: number): string {
 2    const dayMap = new Map<number, string>([
 3        [0, "Sunday"],
 4        [1, "Monday"],
 5        [2, "Tuesday"],
 6        [3, "Wednesday"],
 7        [4, "Thursday"],
 8        [5, "Friday"],
 9        [6, "Saturday"]
10    ]);
11    return dayMap.get(day) ?? "Invalid day";
12}

結論

これらのベストプラクティスに従うことで、TypeScriptでのif文を明確で効率的かつ保守性の高いものにすることができます。型ガード、オプショナルチェイニング、列挙型などTypeScriptの機能を活用することで、コードの可読性と堅牢性を向上させることができます。ベストプラクティスを意識することで、条件を簡潔かつ明確に保ち、理解しやすく保守しやすいコードを記述できます。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video