When using TypeScript, you'll frequently encounter the typeof
operator (which also exists in JavaScript). In TypeScript, typeof
is used in two different contexts:
- JavaScript's runtime
typeof
operator - TypeScript's
typeof
as a type operator
1. JavaScript's Runtime typeof Operator
typeof
returns a string indicating the data type of the operand.
let value = "hello";
console.log(typeof value); // "string"
let number = 32;
console.log(typeof number); // "number"
let func = () => {};
console.log(typeof func); // "function"
The returned values are JavaScript's primitive data types (boolean, number, bigint, string, symbol, null, undefined) along with function and object.
2. TypeScript's Type Operator typeof
In TypeScript, typeof
can also be used in a type
context. In this case, its role changes.
const user = {
name: "John",
age: 30,
isAdmin: true
};
const v_user = typeof user; // object
type User = typeof user;
// Result:
// type User = {
// name: string;
// age: number;
// isAdmin: boolean;
// }
In the example above, v_user
is declared with the const
keyword. Since it needs to be assigned a value, it returns 'object'
, which is the runtime type of user
. However, when typeof
is used after the type
keyword, it returns the TypeScript type.
typeof
should only be used to extract types from values. Using it on something that's already a type will result in an error.
// Incorrect usage
type MyString = string;
type Wrong = typeof MyString; // Error!
// Correct usage
const myString = "hello";
type Correct = typeof myString; // string
typeof Applications
1. Extracting Union Types from Arrays
const colors = ["red", "green", "blue"] as const;
type Colors = typeof colors[number];
// type Colors = "red" | "green" | "blue"
2. Extracting Object Types
// 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;
// }
When used with as const
, the extracted types include the readonly
modifier.
3. Extracting Function Types
You can extract parameter and return types of functions using the utility types ReturnType
and Parameters
.
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;
// }
🔎 References
- Elegant TypeScript
- https://www.typescriptlang.org/docs/handbook/2/typeof-types.html