typescriptgenerics

How TS generics return record or simple value according to type of param?


I would like to write a function with proper type support, and with the following requirements:

Given the following snippet:

function get<K extends string | string[], V>(key: K): K extends string ? V : Record<string, V> {
    /**
     * Implementation
     * ...
     */
}

Result:

const result1 = get('key'); // result1: unknown
const result2 = get<string, {}>('key'); // result2: {}
const result3 = get<string[], {}>(['key1', 'key2']); // result3: Record<string, {}>

I'd like to eliminate the explicit type decalaration for key here. So I can focus only on the return type of get(...).

Expected:

const result1 = get('key'); // result1: unknown - doesn't matter
const result2 = get<{}>('key'); // result2: {}
const result3 = get<{}>(['key1', 'key2']); // result3: Record<string, {}>

I've tried a couple of ways, but it wasn't worked as I expect.

Is there any best (or better) practice for this?

Thanks


Solution

  • Perhaps you can try overload?

    function get<V>(key: string): V;
    function get<V>(key: string[]): Record<string, V>;
    function get<V>(key: string |string[]): any {
        return 'whatever you want';
    }
    
    const result1 = get('key'); // result1: unknown
    const result2 = get<{}>('key'); // result2: {}
    const result3 = get<{}>(['key1', 'key2']); // result3: Record<string, {}>