TypeScriptを使用していると、typeof
演算子(JavaScriptにも存在する)によく出会います。TypeScriptでは、typeof
は2つのコンテキストで使用されます。
- JavaScriptのランタイム
typeof
演算子 - TypeScriptのタイプ演算子としての
typeof
1. JavaScriptのランタイムtypeof演算子
typeof
はオペランドのデータ型を表す文字列を返します。
jsx
let value = "hello";
console.log(typeof value); // "string"
let number = 32;
console.log(typeof number); // "number"
let func = () => {};
console.log(typeof func); // "function"
返される値は、JavaScriptの基本データ型(boolean, number, bigint, string, symbol, null, undefined)とfunction, objectです。
2. TypeScriptのタイプ演算子typeof
TypeScriptでは、typeof
をtype
コンテキストでも使用できます。この場合、役割が変わります。
tsx
const user = {
name: "John",
age: 30,
isAdmin: true
};
const v_user = typeof user; // object
type User = typeof user;
// 結果:
// type User = {
// name: string;
// age: number;
// isAdmin: boolean;
// }
上記の例のv_user
はconst
キーワードで宣言された変数で使用されています。したがって、値が割り当てられる必要があるため、user
のランタイム型を指す'object'
を返します。しかし、type
キーワードの後に使用されるtypeof
はTypeScriptの型を返します。
typeof
は値から型を抽出する場合にのみ使用してください。すでに型であるものに使用すると、エラーが発生します。
tsx
// 誤った使用法
type MyString = string;
type Wrong = typeof MyString; // エラー!
// 正しい使用法
const myString = "hello";
type Correct = typeof myString; // string
typeofの活用
1. 配列からユニオン型を抽出
tsx
const colors = ["red", "green", "blue"] as const;
type Colors = typeof colors[number];
// type Colors = "red" | "green" | "blue"
2. オブジェクト型の抽出
tsx
// without as const
const config = {
endpoint: "api.example.com",
port: 3000
};
type Config = typeof config;
// type Config = {
// endpoint: string;
// port: number;
// }
// with as const
const config = {
endpoint: "api.example.com",
port: 3000
} as const;
type Config = typeof config;
// type Config = {
// readonly endpoint: "api.example.com";
// readonly port: 3000;
// }
as const
と一緒に使用すると、readonly
が付いて抽出されます。
3. 関数型の抽出
ユーティリティ型ReturnType
とParameters
を活用して、関数のパラメータと戻り値の型を抽出できます。
tsx
function createUser(name: string, age: number) {
return { id: Date.now(), name, age };
}
type User = ReturnType<typeof createUser>;
// type User = {
// id: number;
// name: string;
// age: number;
// }
type Param = Parameters<typeof createUser>
// type Param = {
// name: string;
// age: number;
// }
🔎 参照