概要: このチュートリアルでは、未知の値の型チェックを強制するための TypeScript の unknown 型について学びます。
TypeScript の unknown 型の概要
TypeScript では、unknown
型は、事前に不明な値であり、型チェックが必要な値を保持できます。
unknown
型の変数を宣言するには、次の構文を使用します。
let result: unknown;
Code language: TypeScript (typescript)
any 型と同様に、unknown
型の変数には任意の値を代入できます。例:
let result: unknown;
result = 1;
result = 'hello';
result = false;
result = Symbol();
result = { name: 'John' };
result = [1, 2, 3];
Code language: TypeScript (typescript)
any
型とは異なり、TypeScript は、操作を実行する前に型をチェックします。
たとえば、unknown
値に対してメソッドを呼び出したり、演算子を適用したりすることはできません。そうしようとすると、TypeScript コンパイラはエラーを発行します。
let result: unknown;
result = [1,2,3];
const total = result.reduce((a: number, b:number ) => a + b, 0);
console.log(total);
Code language: TypeScript (typescript)
この例では、result
変数は unknown
型です。配列を result
値に代入しますが、その型は依然として unknown
です。したがって、その配列に対して reduce()
メソッドを呼び出すことはできません。
result
変数に対して reduce()
メソッドを呼び出すには、型アサーションを使用し、TypeScript コンパイラに、result の型が配列であることを明示的に伝える必要があります。例:
let result: unknown;
result = [1, 2, 3];
const total = (result as number[]).reduce((a: number, b: number) => a + b, 0);
console.log(total); // 6
Code language: TypeScript (typescript)
この例では、result
の型が数値の array
であることを TypeScript コンパイラに明示的に伝えています(result as number[]
)。
したがって、問題なく result
配列に対して reduce()
メソッドを呼び出すことができます。
Unknown 型 vs Any 型
次の表は、unknown
型と any
型の主な違いをまとめたものです。
機能 | any | unknown |
---|---|---|
型安全性 | 型安全ではない | 型安全性を強制 |
操作 | チェックなしで操作を実行可能 | 型アサーション(型の絞り込み)なしで操作を実行できない |
ユースケース | 動的な値に役立つが、安全ではない。 | 動的な値に役立ち、使用前に検証が必要なため安全。 |
型チェック | TypeScript コンパイラは、any 変数に対して型チェックを実行しない。 | TypeScript コンパイラは、unknown 変数に対して型チェックを強制する。 |
一般的なシナリオ | JavaScript コードベースを TypeScript に移行するために使用。 | 型検証が必要な外部ソース(API呼び出し、データベースなど)からのデータを処理する場合に使用。 |
TypeScript unknown 型の例
TypeScript の unknown
型を使用する実用的な例をいくつか見てみましょう。
1) 外部データの処理
外部APIからデータを受信する際に、unknown
型を使用して、処理する前に検証を強制できます。
次の例は、fetch メソッドを使用して、https://jsonplaceholder.typicode.com/posts
エンドポイントから API を呼び出す方法を示しています。
const fetchData = async (url: string): Promise<unknown> => {
const response = await fetch(url);
return await response.json();
};
const showPosts = async () => {
const url = 'https://jsonplaceholder.typicode.com/posts';
try {
const posts = await fetchData(url); // unknown type
(
posts as { userId: number; id: number; title: string; body: string }[]
).map((post) => console.log(post.title));
} catch (err) {
console.log(err);
}
};
showPosts();
Code language: TypeScript (typescript)
仕組み。
まず、URLからAPIを呼び出し、JSONデータを返す関数fetchData
を定義します。返されるデータの形状が不明なため、関数は Promise<unknown>
値を返します。
const fetchData = async (url: string): Promise<unknown> => {
const response = await fetch(url);
return await response.json();
};
Code language: TypeScript (typescript)
次に、fetchData()
関数を使用して、エンドポイント https://jsonplaceholder.typicode.com/posts
から API を呼び出す showPosts()
関数を定義します。
const showPosts = async () => {
const url = 'https://jsonplaceholder.typicode.com/posts';
try {
const posts = await fetchData(url); // unknown type
(
posts as { userId: number; id: number; title: string; body: string }[]
).map((post) => console.log(post.title));
} catch (err) {
console.log(err);
}
};
Code language: TypeScript (typescript)
この例では、posts 変数は unknown 型です。
title
プロパティにアクセスする前に、型アサーションを使用して、TypeScript コンパイラに post オブジェクトの配列として扱うように指示します。
posts as { userId: number; id: number; title: string; body: string }[]
Code language: TypeScript (typescript)
3番目に、showPosts()
関数を呼び出します。
showPosts();
Code language: TypeScript (typescript)
2) 型安全なインターフェイスの作成
次の例では、コンソールにログを出力する前に値をフォーマットする関数 format
を定義します。
function format(value: unknown): void {
switch (typeof value) {
case 'string':
console.log('String:', value.toUpperCase());
break;
case 'number':
console.log('Number:', value.toFixed(2));
break;
default:
console.log('Other types:', value);
}
}
Code language: TypeScript (typescript)
この例では、値のメソッドにアクセスする前に、操作が有効であることを保証するために、その型を検証します。
まとめ
unknown
型は、any 型に似ていますが、より制限的です。- 外部ソースから取得したデータで、使用前に検証が必要な場合は、
unknown
型を使用してください。