Special type implementations
The following samples are the common technique taat will use in development process.
typeof
To get the type of a variables.
const MyArray = [
{ name: "Alice", age: 15 },
{ name: "Bob", age: 23 },
{ name: "Eve", age: 38 },
];
type Person = typeof MyArray[number];
// type Person = {
// name: string;
// age: number;
// }
keyof
To get the key terms of a interface / type
.
type Staff = {
name: string;
salary: number;
}
type staffKeys = keyof Staff; // "name" | "salary"
keyof typeof
To get the key terms regading a builded object
.
const preferences = {
language: "en",
theme: 'light'
};
type Preferences = keyof typeof preferences; // "language" | "theme"
as const
To implement fully readonly objects
for types.
Array usage
const optionsList = ['easy', 'normal', 'hard'] as const
type Difficulty = typeof optionsList[number] // "easy" | "normal" | "hard"
export const GESTURE_LIST = ["Unknown", "Closed_Fist", "Open_Palm"] as const
export interface GestureObj {
label: string;
emoji: string;
}
export const GESTURE_DATA: {
[key in typeof GESTURE_LIST[number]]: GestureObj
} = {
"Unknown": {
label: "Unrecognized gesture",
emoji: "โ"
},
"Closed_Fist": {
label: "Closed fist",
emoji: "โ"
},
"Open_Palm": {
label: "Open palm",
emoji: "โ"
}
}
// Types:
// const GESTURE_DATA: {
// Unknown: GestureObj;
// Closed_Fist: GestureObj;
// Open_Palm: GestureObj;
// }
Readonly
A const
for a created object.
interface GestureObj {
label: string;
emoji: string;
}
let gesture : Readonly<GestureObj> = {
label: "Unrecognized gesture",
emoji: "โ"
}
gesture["label"] = "Question" // Error, "label" is read-only property
extends
1. To extends a types / class.
interface Person {
age: number;
occupation: string;
}
interface Author extends Person {
firstName: string;
lastName: string;
}
2. Special usage of accept all but not null
and undefined
.
function funcB<T extends {}>() { }
Record
Create a set of key
and values
pair type object.
interface EmployeeType {
id: number
fullname: string
role: string
}
// Record<number, EmployeeType>
let employees: Record<number, EmployeeType> = {
0: { id: 1, fullname: "John Doe", role: "Designer" },
1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}
type CatNames = "miffy" | "boris" | "mordred";
type CatList = Record<CatNames, {age: number}>
const cats: CatList = {
miffy: { age:99 },
boris: { age:16 },
mordred: { age:600 }
}
ReturnType
Return a function output type
// Normal function
function objectFunc(){
return {
name: "peter",
age: 12
}
}
export type ObjectFuncType = ReturnType<typeof objectFunc>
// For await function
async function objectFuncAsync(){
return {
name: "peter",
age: 12
}
}
export type ObjectFuncAsyncType = Awaited<ReturnType<typeof objectFuncAsync>>
NonNullable
Convert a type to no nullable exist
type Fruits = "Apple" | "Orange" | null // "Apple" | "Orange" | null
type MustHaveFruits = NonNullable<Fruits> // "Apple" | "Orange"
Required
Convert a type object from optional
to required
type Person = {
name: string
gender?: string
}
const tom: Person = { name: "Tom" } // OK
const peter: Required<Person> = { name: "Peter" } // Property Error, gender is required
Parameters
Infer the function parameters to a type.
- With spread parameters
function callPeople(name: string, age: number){
console.log(`Hello ${name}, happy birthday for age ${age}!`);
}
type CallPeopleProps = Parameters<typeof callPeople>
const tomBirthday: CallPeopleProps = ["Tom", 27]
- With object parameters
function callPeopleWithObj(ppl:{ name: string, age: number }){
console.log(`Hello ${ppl.name}, happy birthday for age ${ppl.age}!`);
}
type CallPeopleProps = Parameters<typeof callPeopleWithObj>
// Obtail Raw Scheme
const tomBirthdayArr: CallPeopleProps = [{
name: "Tome",
age: 56
}]
// Obtail Object Scheme
const tomBirthdayObj: CallPeopleProps[0] = {
name: "Tome",
age: 56
}
NoInfer
Infer the input limitations.
function returnFruit<C extends string>(
fruits: C[],
defaultFruits: NoInfer<C>,
) {
return defaultFruits
}
returnFruit(["apple", "orange", "france frice"], "france frice"); // OK
returnFruit(["apple", "orange", "france frice"], "pineapple"); // Type Error
Template Literal Types
Quite useful when you are using HTML size unit checking types.
type Size = number
type SizeUnit = "px" | "vh" | "vw"
// `${number}px` | `${number}vh` | `${number}vw`
type SizeInput = `${Size}${SizeUnit}`
const correct: SizeInput = "10px" // OK
const correct2: SizeInput = "100vh" // OK
// Type '"10%"' is not assignable to type '`${number}px` | `${number}vh` | `${number}vw`'.ts(2322)
const wrong: SizeInput = "10%"
Last updated on