TypeScript any型とunknown型

TypeScriptは、開発者にさまざまな型を提供するプログラミング言語です。

TypeScript any型

TypeScriptで最も便利な型のひとつにany型があります。この型はコードの中で任意の値や型を表現することができ、動的なデータや未知のデータを扱う際に非常に便利になります。

any型は予測不可能なデータを返す外部ライブラリやAPIを扱う際に使われることがあります。たとえば、可変数のプロパティを持つJSONオブジェクトを返すAPIを扱う場合を考えてみましょう。APIから返されたデータをany型で表現し、プロパティにアクセスしてます。

let data: any;
data = { name: "John Smith", age: 35 };
console.log(data.name); // Output: "John Smith"

any型のもう一つの一般的な使用例は、データ型が混在した配列を扱う場合です。たとえば、数値と文字列の配列があり、それを反復処理し、各項目に対して何らかのアクションを実行する場合を考えてみましょう。このような場合、any型を使用して配列を表現し、ループを使用して各項目を反復処理することができます。

let mixedArray: any[] = [1, "hello", 2, "world"];
    for (let item of mixedArray) {
    console.log(item);
}

// 1
// hello
// 2
// world

Note: JSONやAPIについては、コンピュータサイエンスプロジェクト/Library Appで詳しく学習できます。

これらの例以外にも、any型は以下のような様々な場面で使用することができます。

  • ある変数の値を別の型の変数に代入する。
  • 任意の型の値を格納できる変数を作成する。
  • 任意の型の引数を受け取り、任意の型の値を返すことができる関数を作成する。

any型は非常に便利ですが、慎重に使用することが重要です。any型はあらゆる値や型を表すことができるため、コードの予測性が低下し、デバッグが困難になる可能性があります。可能な限り、より具体的な型を使用することが常に最善です。

let num: number = 1;
let anyType: any = "hello";
num = anyType; // Error: Type 'string' is not assignable to type 'number'

numには1が代入され、number型の変数として宣言されています。anyTypeにはhelloという値が代入され、any型の変数として宣言されています。

文字列であるanyTypeの値を数値であるnumに代入する際に、エラーが発生します。TypeScriptは変数numの値を、本来の型(数値)とは異なる文字列の値に再代入することを阻止しています。

TypeScript unknown型

TypeScriptのunknown型は、TypeScript 3.0から導入された新しい型です。任意の値や型を表すことができるという点では、any型と似ていますが、より使い方が限定されています。

any型とunknown型の大きな違いは、any型が直接使用できるのに対し、unknown型は使用する前に変数の型を確認する必要があることです。

unknown型はプロパティへのアクセスやメソッドの呼び出しを行うことができません。そのため、前述のように変数の型を確認する必要があります。

let data: unknown;
data = "hello";
if (typeof data === "string") {
    console.log(data.toUpperCase()); // Output: "HELLO"
} else {
    console.log("Data is not a string");
}

data = 100;
if (typeof data === "number") {
    console.log(data * 2); // Output: 200
} else {
    console.log("Data is not a number");
}

この例では、まず変数dataに文字列値helloを代入し、使用する前にデータの型を確認し、型が文字列の場合はtoUpperCase()メソッドを使用して大文字に変換しています。次に、変数dataに数値100を代入し、使用する前にデータの型を確認し、型が数値の場合は2倍しています。

どちらの場合も、データを表すのにunknown型を使っていますが、使う前に型チェックを行なっていることがわかります。これがunknownとanyの大きな違いで、unknownは使う前に型チェックをする必要がありますが、anyは何もチェックせずにそのまま使うことができます。

class Person {
    name: string;
    age: number;
}

let data: unknown;
data = new Person();
if (data instanceof Person) {
    data.name = "John Smith";
    data.age = 35;
    console.log(data); // Output: Person { name: 'John Smith', age: 35 }
} else {
    console.log("Data is not an instance of Person");
}

この例では、まず変数dataにPersonクラスのインスタンスを代入し、それがPersonクラスのインスタンスであるかどうかを調べてから使用しています。もしそうであれば、dataオブジェクトにnameとageプロパティを設定し、ログを記録します。

TypeScript unknown型の型アサーション

unknown型では、型アサーションを使用することができます。型アサーションは、TypeScriptコンパイラが値から推測できない場合でも、ある変数が特定の型であることを伝えるための方法です。

型アサーションはasキーワードを使用し、変数の型を特定の型に変更することができます。しかし、変数の型が期待したものと異なる場合、実行時エラーになる可能性があるため、注意して使用する必要があります。

let data: unknown = "hello";
let str: string = data as string;
console.log(str.toUpperCase()); // "HELLO"

let data1: unknown = 100;
console.log((data1 as number) * 2); // 200

最初の例では、まず変数dataが文字列であることを表明し、toUpperCase()メソッドを使用しています。次の例では、変数data1が数値であることを表明し、それを2倍しています。

どちらの場合も、型アサーションを使って、変数dataとdata1が特定の型であることをTypeScriptコンパイラに伝えてます。ただし、変数の型が確かでない場合や期待する型と異なる場合、実行時エラーになる可能性があるため、注意して使用する必要があります。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート