typescripttuples

Typescript: object type to array type (tuple)


I have this:

interface Obj {
    foo: string,
    bar: number,
    baz: boolean
}

The desired type is this tuple:

[string, number, boolean]

How can I convert the interface to the tuple?

Update:

My original problem is: I make some opinionated library with a declarative spirit, where a user should describe parameters of a function in an object literal. Like this:

let paramsDeclaration = {
  param1: {
    value: REQUIRED<string>(),
    shape: (v) => typeof v === 'string' && v.length < 10
  },
  param2: {
    value: OPTIONAL<number>(),
    ...
  },
}

Then the library takes this object and creates a function with parameters from it:

   (param1: string, param2?: number) => ...

So, making such function is not a problem, the problem is to correctly type it, so that user gets good code-completion (IntelliSense).

P.S. I know it's not solvable, but it would be interesting to know what is the closest possible workaround/hack.


Solution

  • Not really an answer to the question, but since I don't actually think its possible to do, hopefully this is at least helpful in some way:

    function REQUIRED<T>(): T {
        //...
    }
    function OPTIONAL<T>(): T {
        //...
    }
    
    interface ParamsDeclaration {
        readonly [paramName: string]: {
            readonly value: any;
            readonly shape?: Function;
        };
    }
    
    type Func<T> = T extends {
        readonly [paramName: string]: {
            readonly value: infer U;
        };
    } ? (...params: Array<U>) => void
        : never;
    
    function create<T extends ParamsDeclaration>(paramsDeclaration: T): Func<T> {
    
        // ...
    }
    
    const paramsDeclaration = {
        param1: {
            value: REQUIRED<string>(),
            shape: (v: any) => typeof v === 'string' && v.length < 10
        },
        param2: {
            value: OPTIONAL<number>(),
            //...
        },
    };
    // Type is '(...params: (string | number)[]) => void'
    const func1 = create(paramsDeclaration);
    func1('1', 2); // Ok
    func1(2, '1'); // Ok, but I assume not what you want
    func1(Symbol()); // TS error