Here is where TypeScript stops being “JavaScript with types” and becomes a superpower. Until now we have defined types manually. But what if we could automatically generate types from our code?
typeof: Extracting the DNA
In JS, typeof returns a string (“string”, “number”, “object”).
In TS, if we use it in a type context, it returns the full type.
const settings = {
theme: "dark",
notifications: true,
version: 1.0
};
// Instead of writing the interface manually...
// type Settings = { theme: string; notifications: boolean; version: number }; 😴
type Settings = typeof settings;
// 🪄 Boom! TS just wrote the interface for you.const settings = {
theme: "dark",
notifications: true,
version: 1.0
};
// Instead of writing the interface manually...
// type Settings = { theme: string; notifications: boolean; version: number }; 😴
type Settings = typeof settings;
// 🪄 Boom! TS just wrote the interface for you.This is brutal for APIs or third-party libraries (or our own configuration constants). We have a “Single Source of Truth”: the value. The type adapts itself.
API Trick
Imagine you have a JSON response from an API. Instead of writing the interface by hand, you can paste the JSON as a constant (mock) and extract the type from there. Thus, the example serves as documentation and type generator at the same time.
keyof: Give me the keys
keyof takes a Type and returns a Union of its keys.
interface User {
name: string;
age: number;
email: string;
}
type UserKeys = keyof User;
// It is equivalent to: "name" | "age" | "email"interface User {
name: string;
age: number;
email: string;
}
type UserKeys = keyof User;
// It is equivalent to: "name" | "age" | "email"What is it for? So that we cannot ask for properties that do not exist.
function getProperty(user: User, key: keyof User) {
return user[key];
}
const me: User = { name: "Alice", age: 39, email: "..." };
getProperty(me, "name"); // ✅
getProperty(me, "password"); // ❌ Error: Argument of type '"password"' is not assignable...function getProperty(user: User, key: keyof User) {
return user[key];
}
const me: User = { name: "Alice", age: 39, email: "..." };
getProperty(me, "name"); // ✅
getProperty(me, "password"); // ❌ Error: Argument of type '"password"' is not assignable...The Ultimate Combo: keyof typeof
This is one of the most used combinations in real TypeScript. It is used when we want to get the keys of an object/value that already exists (not an interface).
typeof object-> Gives us the Type of the object.keyof (Type)-> Gives us the keys of that Type.
const COLORS = {
red: "#FF0000",
green: "#00FF00",
blue: "#0000FF"
};
type ColorName = keyof typeof COLORS;
// "red" | "green" | "blue"
function paint(color: ColorName) { ... }
paint("red"); // ✅
paint("yellow"); // ❌ Errorconst COLORS = {
red: "#FF0000",
green: "#00FF00",
blue: "#0000FF"
};
type ColorName = keyof typeof COLORS;
// "red" | "green" | "blue"
function paint(color: ColorName) { ... }
paint("red"); // ✅
paint("yellow"); // ❌ ErrorLet’s try it!
Let’s use the editor. Let’s create a config object with various options. Let’s use typeof to extract its type and create a function that receives that type.
In Part 6 we will see Generics, the tool that allows us to create reusable components and functions that work with any type (the famous <T>).