TypeScript Exhaustiveness Checking Part 2

type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";

const sendRequest = (url: string, method: HttpMethod) => {
    switch (method) {
        case 'DELETE':

            break;
        case 'GET':

            break;
        case 'POST':

            break;
        case 'PUT':

            break;
        default:
            const exhaustiveCheck: never = method; // ✅ no error
            throw new Error(`Unhandled case: ${exhaustiveCheck}`);
    }
};
type Fruit = 'banana' | 'orange' | 'mango';

function exhaustiveCheck(param: never): never {
    throw new Error('should not reach here')
}

function makeDessert(fruit: Fruit) {
    switch (fruit) {
        case 'banana': return 'Banana Shake'
        case 'orange': return 'Orange Juice'
    }
    exhaustiveCheck(fruit) // 🚫 ERROR! `mango` is not assignable
}
Continue reading

TypeScript Exhaustiveness Checking

Exhaustiveness checking is a good feature when you use switch block. Assume that you need to check a value of variable which data type is union type as shown below screenshot.

Shape is a discriminated union which consists of three types named Circle, Square and Triangle.

kind field is shared in Circle, Square and Triangle types so that if developer forgets to use any of kind field value in switch block, TypeScript will error in coding-time.

Notice that there is a red line in line 347, it is due to missing triangle case in switch block.

This is the error shown in the code.

After adding triangle case in line 346, the error disappeared.

Continue reading

TypeScript Language Basics

Primitive Types (Boolean, Number, String)

Boolean

let isDone: boolean = false;

Number

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;

String

let color: string = "blue";

let fullName: string = 'Bob Bobbington';

let age: number = 37;

let sentence: string = `Hello, my name is ${fullName}.
 
I'll be ${age + 1} years old next month.`;

Arrays

let list: number[] = [1, 2, 3];

let list2: Array<number> = [1, 2, 3];
Continue reading

TypeScript Union Type and Distributive Conditional Types

When conditional types act on a generic type, they become distributive when given a union type.

So, in order to support Union Type, user Conditional Type because it works as loop.

Generic Type with Single Type without Distributive Conditional Type

Generic Type with Union Type without Distributive Conditional Type (This doesn't work)

Notice that conditional type is not use in line 96 so ObjectFieldNames function couldn't retrieve field names in line 102.

Generic Type with Union Type and Distributive Conditional Type

You can think Union type as array, so conditional type will iterate for each type in Union.

For example, notice that PersonType | UserType is used as Union Type in line 113, and field names of both types are listed in Popup window as shown in below screenshot.

PersonType | UserType | EventType is used as Union Type in line 115, so Popup window showed more fields in the following screenshot.

for example PersonType | UserType | EventType, then ObjectFieldNames<T> is keyof PersonType | keyof UserType | keyof EventType