Show pageOld revisionsBacklinksFold/unfold allBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== TS ====== typehero <code ts> declare const config: Chainable const result = config .option('foo', 123) .option('name', 'type-challenges') .option('bar', { value: 'Hello World' }) .get() // expect the type of result to be: interface Result { foo: number name: string bar: { value: string } } </code> ===== Type Argument Inference in TypeScript ===== ==== Goal: Understand how TypeScript infers type arguments ==== <code typescript> type Chainable<T = {}> = { option<K extends string, V>(key: Exclude<K, keyof T>, value: V): Chainable<Omit<T, K> & {[P in K]: V}> get(): T } </code> Why K is Inferred, Not T? TypeScript's inference flows from unknown type parameters based on known argument types: <code typescript> // When you write: config.option('database', 'mysql') // TypeScript thinks: // - Receiver type: Chainable<{}>, so T = {} (KNOWN) // - First argument: 'database' (literal string) // → Must infer K = 'database' (UNKNOWN → INFERRED) // - Second argument: 'mysql' (literal string) // → Must infer V = 'mysql' (UNKNOWN → INFERRED) </code> What If T Were Also a Type Parameter? If we hypothetically made T also inferrable, it would create ambiguity: <code typescript> // Hypothetical (problematic) design: type BadChainable = { option<T, K extends string, V>( key: Exclude<K, keyof T>, value: V ): Chainable<Omit<T, K> & {[P in K]: V}> } // How would TypeScript know what T should be? // There would be no way to infer T from the arguments! </code> ===== The NoInfer Utility Type ===== <code lang=typescript el=true > function createStreetLight<C extends string>(colors: C[], defaultColor?: C) { // ... } createStreetLight(["red", "yellow", "green"], "blue"); // ^^^^^ defaultColor?: "red" | "yellow" | "green" | "blue" | undefined // But I don't want blue, because blue is not the color in colors. // So function createStreetLight<C extends string>(colors: C[], defaultColor?: NoInfer<C>) { // ... } createStreetLight(["red", "yellow", "green"], "blue"); // ~~~~~~ // error! // Argument of type '"blue"' is not assignable to parameter of type '"red" | "yellow" | "green" | undefined'. </code> ===== dokuwiki docker upgrade ===== <code lang=bash> tar -czvf "$(date +'%Y-%m-%d_%H-%M-%S')_config.tar.gz" ./config mv *config.tar.gz ./backup docker compose down && docker compose pull && docker compose up -d </code> ===== Tuple Map ===== we can use mapped types for creating tuples. It's because tuple properties are indexes. <code typescript> type A<T extends unknown[]> = { [P in keyof T] : T[P] } type a = A<[1,2,3]> // ^ type a = [1, 2, 3] </code> note/tue_jun_17_2025.txt Last modified: 2025/06/17 13:00by lingao