My TypeScript cheatsheet
keyof
The keyof operator takes an object type and produces a string or numeric literal union of its keys.
For example, it can be used to create a more readable and maintainable type for an object:
ts
interface IUser {
name: string
age: number
}
type UserKeys = keyof IUser // "name" | "age"
Use the keyof operator to create more type-safe functions
ts
function getValue<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
const user: IUser = { name: 'Mike', age: 18 }
getValue(user, 'name') // 'Mike'
getValue(user, 'gender') // Compile-time error: "gender" is not a key of IUser
Exclude
Exclude<T, U> removes members of a union that are assignable to U. To remove properties from an object type, use Omit<T, Keys>.
ts
interface IUser {
name: string
age: number
}
type UserWithoutAge = Omit<IUser, 'age'> // { name: string }
type T0 = Exclude<'a' | 'b' | 'c', 'a'> // "b" | "c"
Official Exclude implementation
ts
type Exclude<T, U> = T extends U ? never : T
ReturnType
Grab the type returned from a function
ts
const sum = (a: number, b: number) => a + b
type SumResult = ReturnType<typeof sum> // number
Awaited
Awaited<T> unwraps a promise type, including nested promises.
ts
const sumAsync = async (a: number, b: number) => a + b
type SumResult = Awaited<ReturnType<typeof sumAsync>> // number
Generic
ts
function toLabelValue<T, LabelKey extends keyof T, ValueKey extends keyof T>(
labelKey: LabelKey,
valueKey: ValueKey,
obj: T
) {
return {
label: obj[labelKey],
value: obj[valueKey],
}
}
interface Lib {
id: number
name: string
isPublic: boolean
}
const lib = { id: 1, name: 'hi', isPublic: true }
// type: { label: string, value: number }
const labelValue = toLabelValue('name', 'id', lib)