Hacker News new | ask | show | jobs
by DecoPerson 594 days ago
Sharing my TypeScript Result type for anyone who’s crazy like me and wishes they had “if let” and doesn’t want “.value” everywhere.

You can do this:

    const user = await fetchUserDTO(123);
    // user is Result<UserDTO, Error>
    if(!isOk(user)) { something(user.err); return; }
    user.name; // user is narrowed to UserDTO
Source:

    export const FailSym: unique symbol = (globalThis as any).____FailSym ?? Symbol('FailSym');
    (globalThis as any).____FailSym = FailSym;
    export type Result<T, E> = T | {
        [FailSym]: true,
        err: E
    }
    
    export function Ok<T>(val: T): Result<T, never> { return val; }
    export function Fail<E>(err: E): Result<never, E> { return {[FailSym]: true, err}; }
    
    export function isOk<T, E>(val: Result<T, E>): val is T { return !(typeof val == 'object' && val != null && FailSym in val); }
    export function isFail<T, E>(val: Result<T, E>): val is Result<never, E> { return typeof val == 'object' && val != null && FailSym in val; }
    
    export function resultify<T, E>(promise: Promise<T>): Promise<Result<T, E>> {
        return promise.then(Ok, err => Fail(err as any));
    }