TypeScript

Table of Contents

1. any v.s. unknown

unknown is the parent type of all other types. it's a regular type in the type system.

any means "disable the type check". it's a compiler directive.

Much like any, any value is assignable to unknown; however, unlike any, you cannot access any properties on values with the type unknown, nor can you call/construct them. Furthermore, values of type unknown can only be assigned to unknown or any.

2. Type-level programming

// https://github.com/microsoft/TypeScript/issues/23182#issuecomment-583330532
type NeverAlternative<T, P, N> = [T] extends [never] ? P : N;

type Union<T, U> = NeverAlternative<T, U, T | U>;

class C<T = never> {
    frob<U>(obj: Record<keyof U, any>): C<Union<T, keyof U>> {
        return new C<Union<T, keyof U>>();
    }

    get(key: T) {

    }
}

// x : C<never>
const x = new C();

// y : C<'a' | 'b'>
const y = x.frob({ 'a': 1, 'b': 2 });

y.get('a');

// z : C<'a' | 'b' | 'bleh'>
const z = y.frob({ bleh: 32 })

2.1. Plural and singluar strings

type Plural<S extends string> = S extends `${infer _}s` ? S : `${S}s`;
type Singular<S extends string> = S extends `${infer U}s` ? U : S;

3. Backlinks

Created: 2025-03-20 Thu 01:16