TypeScript unknown型を安全に確認して使用する
unknownは、どのような値が入っているか分からないことを表す型です。
外部から受け取ったJSONやcatchした値を、確認せず操作したくない場合に使います。anyは型チェックを無効にしますが、unknownは確認するまで操作を許しません。値が不明であるという事実を型に残すことが、unknownを選ぶ理由です。
anyとの違い
anyは型の確認をせずに操作できます。
const value: any = 10;
value.toUpperCase(); // コンパイルできるが、実行時にエラーunknownでは、型を確認するまで操作できません。
const value: unknown = 10;
// value.toUpperCase(); // TypeScriptのエラー外部から受け取る値など、型が分からない値にはunknownを使うと安全です。
typeofで型を確認する
const toUpperCase = (value: unknown): string => {
if (typeof value !== 'string') {
return '';
}
return value.toUpperCase();
};typeof value === 'string'を確認した範囲では、TypeScriptがvalueをstring型として扱います。
Errorかどうか確認する
catchで受け取る値も、常にErrorとは限りません。
try {
await saveData();
} catch (error: unknown) {
if (error instanceof Error) {
console.error(error.message);
} else {
console.error('不明なエラーが発生しました。');
}
}instanceof Errorを確認してからmessageを参照します。
オブジェクトのプロパティを確認する
type User = {
userId: string;
name: string;
};
const isUser = (value: unknown): value is User => {
if (typeof value !== 'object' || value === null) return false;
const user = value as Record<string, unknown>;
return typeof user.userId === 'string'
&& typeof user.name === 'string';
};戻り値のvalue is Userを型述語と呼びます。
const data: unknown = JSON.parse(jsonText);
if (isUser(data)) {
console.log(data.name);
}const user = data as Userと書いても、実際のデータがUser型になるわけではありません。外部データはプロパティを確認するか、検証ライブラリを使用します。
unknownを使うと、型が分からない値を操作する前に確認が必要になり、実行時エラーを減らせます。