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
}
interface Point {
    x: number;
    y: number;
}

interface EventArgs { }

interface KeyEventArgs extends EventArgs {
    modifiers: 'CTRL' | 'SHIFT' | 'ALT';
    keyValue: number;
    shift: boolean;
    ctrl: boolean;
    alt: boolean;
    handled: boolean;
}

interface KeyPressEventArgs extends EventArgs {
    handled: boolean;
    keyChar: string;
}

interface MouseEventArgs extends EventArgs {
    x: number;
    y: number;
    location: Point;
    delta: number;
    clicks: number;
    button: 'LEFT' | 'RIGHT';
}



type AppEvent =
    | { kind: "Click"; } & EventArgs
    | { kind: "DoubleClick"; } & EventArgs
    | { kind: "KeyUp"; } & KeyEventArgs
    | { kind: "KeyPress"; } & KeyPressEventArgs
    | { kind: "KeyDown"; } & KeyEventArgs
    | { kind: "MouseClick"; } & MouseEventArgs
    | { kind: "MouseDoubleClick"; } & MouseEventArgs
    | { kind: "MouseDown"; } & MouseEventArgs
    | { kind: "MouseUp"; } & MouseEventArgs
    | { kind: "MouseMove"; } & MouseEventArgs
    | { kind: "MouseWheel"; } & MouseEventArgs
    | { kind: "MouseEnter"; } & EventArgs
    | { kind: "MouseHover"; } & EventArgs
    | { kind: "MouseLeave"; } & EventArgs;

function handleEvent(event: AppEvent) {

    switch (event.kind) {
        case 'Click':
            console.log(`It is ${event.kind} event`);
            break;
        case 'DoubleClick':
            console.log(`It is ${event.kind} event`);
            break;
        case 'KeyDown':
            console.log(`It is ${event.kind} event`);
            break;
        case 'KeyPress':
            console.log(`It is ${event.kind} event`);
            break;
        case 'KeyUp':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseClick':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseDoubleClick':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseDown':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseUp':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseEnter':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseHover':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseLeave':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseMove':
            console.log(`It is ${event.kind} event`);
            break;
        case 'MouseWheel':
            console.log(`It is ${event.kind} event`);
            break;
        default:
            const exhaustiveCheck: never = event;
            throw new Error(`Unrecognized Method ${exhaustiveCheck}`);
    }
}

Leave a Reply