公開日

【TypeScript】型ガードを試す

この記事では、TypeScriptの型ガードを使用して型の不一致によるエラーを解決する方法について解説します。具体的には、`string | undefined`型のプロパティを`string`型の変数に割り当てる際に発生する問題と、型ガードを用いた解決策を示します。

著者
  • avatar
    名前
    Lan oo
    Twitter
    @Lan_o_sir
  • Freelance IT Engineer
目次

TypeScriptで開発をしていると、型安全を保ちながらコードを書くことが求められます。
この記事では、TypeScriptの強力な機能である型ガードについて解説し、エラーを回避する方法を示します。

検証環境

moduleversion
TypeScript5.0.0

問題のコード

まず、以下のコードを見てみましょう。

type Prop = {
	name: string | undefined;
};

export class User {
	constructor(prop: Prop) {
		if (!this.isValid(prop)) throw new Error();
		const userName: string = prop.name; // TSエラー(Type 'undefined' is not assignable to type 'string'.)
	}

	private isValid(prop: Prop) {
		return !!prop.name;
	}
}

このコードではUserクラスのコンストラクタ内で、バリデーションを実行した後に、propオブジェクトのnameプロパティをstring型の変数userNameに割り当てようとしています。
しかし、nameプロパティはstring型かundefined型のどちらかを取るため、この割り当ては型の不一致で以下のエラーが発生します。
Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.

型ガードを使った解決策

この問題を解決するために、TypeScriptの型ガード(type guard function)を利用します。
型ガードを使うと、特定のスコープ内で変数の型を絞り込むことができます。以下のようにisValidメソッドを変更します。

type Prop = {
	name: string | undefined;
};

export class User {
	constructor(prop: Prop) {
		if (!this.isValid(prop)) throw new Error();
		const userName: string = prop.name;
	}

	private isValid(prop: Prop): prop is { name: string } {
		return !!prop.name;
	}
}

ここでは、isValidメソッドの戻り値の型アノテーションを変更しています。
prop is { name: string }という型アノテーションは、isValidメソッドが真を返した場合にはprop.nameがstring型であることをTypeScriptの型システムに通知します。
これにより、isValidメソッドが真を返した後は、prop.nameを安全にstring型として扱うことができるようになります。

まとめ

TypeScriptの型ガードは、型の不確実性を扱う強力な手段です。
今回示したように、型ガードを適切に使用することで、コンパイル時に型エラーを防ぎつつ、実行時の安全性を保つことができます。
TypeScriptを使用する際は、このような型システムの特徴を活かして、より安全で読みやすいコードを心がけましょう。