Skip to Content
πŸ“ Notes🌐 LanguagesTypeScriptAdvance Use Cases

Typescript Advance Use Cases

Some use cases of how those type helps.

Conditions API

Output the regarding type for user input type (Using HTTP standards as example)

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; type ApiOptions = | { method: "GET"; body?: undefined } | { method: Exclude<HttpMethod, "GET">; body: Record<string, any> }; function fetchApi( url: string, options: ApiOptions ) { /* ... */ } // βœ… OK: GET without body fetchApi('https://api.com', { method: "GET" }); // βœ… OK: GET with explicit undefined (still allowed) fetchApi('https://api.com', { method: 'GET', body: undefined }); // βœ… OK: POST with body fetchApi('https://api.com', { method: 'POST', body: { id: 1 } }); // ❌ WRONG: Property 'body' is missing... fetchApi('https://api.com', { method: 'POST' }); // ❌ WRONG: Type '{ id: number; }' is not assignable to type 'undefined'. fetchApi('https://api.com', { method: 'GET', body: { id: 1 } });

Type value filter

Assume we have a fixed object like this, and we want GET only records

type AppRouteMap = { "/users/dummyTest": "GET"; "/users/checkAvaiableUser": "POST"; "/files/uploadSignatureTest": "POST"; "/files/uploadDocsTest": "POST"; "/testing/dummyTest": "GET"; } type OnlyGetRoutes = { [K in keyof AppRouteMap as AppRouteMap[K] extends "GET" ? K : never]: AppRouteMap[K] }; // type OnlyGetRoutes = { // "/users/dummyTest": "GET"; // "/testing/dummyTest": "GET"; // } export type RoutersPathLessStrictOnlyGet = `${keyof OnlyGetRoutes}${string}`; // type RoutersPathLessStrictOnlyGet = `/users/dummyTest${string}` | `/testing/dummyTest${string}`

This time we keep keys that start with β€œ/files/β€œ:

type FilesOnly = { [K in keyof AppRouteMap as K extends `/files/${string}` ? K : never]: AppRouteMap[K] }; // { // "/files/uploadSignatureTest": "POST"; // "/files/uploadDocsTest": "POST"; // }

Type reminder for function params

Assume you have a const object, and you are going to require users to input related names and reminder the regarding array items.

const contactList = { "Peter": ["123", "A1"], "May": ["345", "B2"], "Tom": ["567", "C3"], } as const // "Peter" | "May" | "Tom" type Names = keyof typeof contactList function getNames< K extends Names, // When a name match, it will refer to the record list for the value N extends typeof contactList[K][number] >( key: K, number: N ) { return `${key}: ${number}` } // βœ… OK getNames("May", "345") getNames("Tom", "C3") // ❌ WRONG getNames("Peter", "999") // Argument of type '"999"' is not assignable to parameter of type '"123" | "A1"'. // Argument of type '"Ken"' is not assignable to parameter of type '"Peter" | "May" | "Tom"'.ts(2345) getNames("Ken", "B2")

Type reminder for objects

When you are require to have several conditions of what key value will refer to what objects (For type reminder):

interface Student { name: string; age: number; } interface CsStudents extends Student { major: 'cs'; mainSkill: "Python" | "C++" | "Javascript" loveToCode: boolean } interface PhyStudents extends Student { major: 'phy'; mainSkill: "Force" | "Electron" } interface MathStudents extends Student { major: 'math'; mainSkill: "d/dx" | "stats" | "intergrations" } export type UniversityStudent = | CsStudents | PhyStudents | MathStudents export const studentList : UniversityStudent[] = [ // [βœ… OK]: When the major is "cs", the mainSkill will refer to "Python" | "C++" | "Javascript" { name: "Tom", age: 21, major: "cs", mainSkill: "Javascript", loveToCode: true }, // [βœ… OK]: Will auto refer to "PhyStudents" for major is phy { name: "Peter", age: 20, major: "phy", mainSkill: "Force"}, // [❌ WRONG]: Types of property 'mainSkill' are incompatible. { name: "May", age: 22, major: "cs", mainSkill: "Force"}, // [❌ WRONG]: 'loveToCode' does not exist in type 'MathStudents'. { name: "Wong", age: 20, major: "math", mainSkill: "stats", loveToCode: true}, ]

In simply way, you can write like this:

type StorageConfig = | { type: 's3'; bucket: string; region: string } | { type: 'local'; directory: string; createIfMissing: boolean }; function initStorage(config: StorageConfig) { if (config.type === 's3') { console.log(config.bucket); // βœ… OK console.log(config.createIfMissing); // ❌ WRONG, createIfMissing only exist when type is local } }
Last updated on