Given the following type in Typescript
type MyType = {
foo: int,
bar: string
}
can I define a mapping (preferriby using mapped conditional types) so that I get
type MyTypeFn = (foo: int, bar: string) => MyType
Not really. There's no way to enumerate the keys of an object in any predictable or usable order. You can do something programmatic, but you have to start with a more easily manipulable type, like this:
type MySchema = [['foo', number], ['bar', string]]
which is a tuple of 2-tuples representing the key-value pairs in your type. Then you can synthesize MyType
using a (TSv2.8 and up) type function such as:
type MakeMyType<S extends [string, any][], M = S[number]> =
{ [K in S[number][0]]: M extends [K, any] ? M[1] : never }
which you can verify:
type MyType = MakeMyType<MySchema>
// inspects as { foo: number; bar: string }
And then you can synthesize MyTypeFn
using a type function such as:
type MakeMyFunction<S extends [string, any][], L = S['length'], T = MakeMyType<S>> =
L extends 0 ? () => T :
L extends 1 ? (a0: S[0][1]) => T :
L extends 2 ? (a0: S[0][1], a1: S[1][1]) => T :
L extends 3 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1]) => T :
L extends 4 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1], a3: S[3][1]) => T :
L extends 5 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1], a3: S[3][1], a4: S[4][1]) => T :
L extends 6 ? (a0: S[0][1], a1: S[1][1], a2: S[2][1], a3: S[3][1], a4: S[4][1], a5: S[5][1]) => T :
(...args: S[number][1][]) => T
Note how there's no programmatic way to do variable-length argument lists, so the best you can do is make cases up to some fixed maximum length as above. Let's verify:
type MyTypeFn = MakeMyFunction<MySchema>
// inspects as (a0: number, a1: string) => { foo: number; bar: string; }
And yes, the parameter names are also lost (foo
and bar
become a0
and a1
). This doesn't affect type compatibility of a function signature, where the parameter names are not important. But I'm guessing you want those parameter names for hinting when using or implementing the function. If so, then that's another "not really".
So that's a long drawn-out way of saying "not really" multiple times. Oh well, Maybe it's been of some help anyway. Good luck!