型演算子【個人学習まとめ】
型演算子
keyof
keyof
演算子は指定されたオブジェクト型からプロパティのキーを抽出し、それらを結合したユニオン型を生成することができます。
keyof 演算子
interface Person {
name: string;
age: number;
hobbies: string[];
}
type PersonKeys = keyof Person;
// name | age | hobbies 型
上記ではPerson
インターフェイスに対してkeyof
演算子を使用しています。
これにより、Person
型のプロパティキーであるname
、age
、hobbies
をリテラル型のユニオンとしてPersonKyes
型に抽出することが可能です。オブジェクトのプロパティ名を安全に参照することができますね。
keyof
演算子を使用せずに、次のように宣言しても同じ意味になります。
type PersonKeys = "name" | "age" | "hobbies";
typeof
演算子を使って、オブジェクトの特定のプロパティにアクセスするコードを使って使用例を確認してみましょう。
console.log(`新任の先生の名前は、${getProperty(teacher, "name")} です。`);
→ 新任の先生の名前は、○○先生 です。
関数getProperty
は引数に
-
Person
型のオブジェクト - オブジェクトのプロパティ名
を必要とします。
戻り値は、第 2 引数に指定されたプロパティの値を返却します。
第 2 引数にkeyof
演算子を使用することによって、Person
型に定義されているプロパティのキーのみが引数に指定することができます。
Person
型に存在しないプロパティのキーaddress
を指定するとエラーが発生します。
console.log(`住所は、${getProperty(teacher, "address")} です。`);
→ 型 '"address"' の引数を型 'keyof Person' のパラメーターに割り当てることはできません。
仮に関数getProperty
の第 2 引数を単純なstring
型だったとしましょう。
この場合、存在しないプロパティのキーaddress
が渡されたと気が付かずに、コードを実行してからエラーが発生する可能性があります。
これを未然に防ぐためにも、keyof
演算子を利用することによって、関数getProperty
に渡された引数がPerson
型かつ、実際に存在するプロパティ名であることを証明でき、型が安全であることが保たれます。
typeof
これまでの学習で何度かtypeof
演算子が出てきました。それは JavaScript のtypeof
演算子でした。
TypeScript には独自のtypeof
演算子が存在します。
JavaScirpt のtypeof
演算子と TypeScript 独自のtypeof
演算子の違いを確認していきましょう。
JavaScript の typeof 演算子
指定した値の型を調べることができます。
こちらの記事では型の絞り込みをするためにtypeof
演算子を使用しました。
console.log(typeof true);
→ boolean
console.log(typeof 1);
→ number
console.log(typeof "こんにちは!");
→ string
console.log(typeof [1, 2, 3]);
→ object
console.log(typeof { a: 1, b: 2 });
→ object
TypeScript の typeof 演算子
一方、TypeScript 独自のtypeof
演算子は変数から型を抽出し、型情報を返却する演算子です。
抽出した型情報は新しい変数の型注釈や関数の引数として利用することができます。
const book = {
title: "○○の教科書",
price: 1000,
publicationForm: ["紙", "電子", "読み上げ"],
};
type BookType = typeof book;
上記では、変数book
からtypeof
演算子を使って、変数book
の型情報を取得し型BookType
を作成しています。
この作成した型BookType
を関数の引数の型情報として利用することもできます。
function getBookInfo(info: BookType) {
console.log(`本のタイトルは「${info.title}」です。`);
→ 本のタイトルは「○○の教科書」です。
console.log(`値段は「${info.price}」円です。`);
→ 値段は「1000」円です。
console.log(`発行形態は「${info.publicationForm}」です。`);
→ 発行形態は「紙,電子,読み上げ」です。
}
getBookInfo(book);
keyof と typeof の組み合わせ
keyof
演算子とtypeof
演算子を組み合わせることによって、指定されたオブジェクトのキーの型情報を抽出することができます。
const student = {
no: 123456789,
name: "テスト 太郎",
club: "野球",
};
function getStudentDetail(key: keyof typeof student) {
return student[key];
}
console.log(getStudentDetail("name"));
→ テスト 太郎
上記の例では変数student
オブジェクトから型情報を作成し、関数getStudentDetail
の引数key
の型情報として利用しています。
変数student
オブジェクトに存在しないプロパティを、関数getStudentDetail
に指定しようとするとエラーとなります。
getStudentDetail("gakunen")
→ 型 '"gakunen"' の引数を型 '"no" | "name" | "club"' のパラメーターに割り当てることはできません。
これにより、関数getStudentDetail
内では変数student
オブジェクトに存在しないプロパティにアクセスすることはできず、タイプミスなどを防ぐことができます。
keyof
演算子とtypeof
演算子を組み合わせることによって、宣言されたオブジェクトから動的に取得することができます。
Discussion