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.
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