Typescript: type transformation for mapping object properties to function parameters

Created on 15 Nov 2016  ·  8Comments  ·  Source: microsoft/TypeScript

now that we have map types it would nice being able to map properties to function parameters

type Constructor<T> = (P in T) => T;
interface Data {
    name: string;
    value: number;
}
type CreateData = Constructor<Data>;

would desugar to

type CreateData = (name: string, value: number) => Data;
In Discussion Suggestion

Most helpful comment

Why not just make object spread types valid in argument positions (so the spread type flattens into part of the argument list)? I think that would solve this elegantly:

type Constructor<T> = (...T) => T;
interface Data {
    name: string;
    value: number;
}
type CreateData = Constructor<Data>;

It also makes it obvious how to combine a spread object with normal arguments, and removes a confusingly useless type parameter.

All 8 comments

I can see this, paired with substraction types, being used for

  • ADT constructors
  • bind / apply

This is really interesting

What determines the order of the parameters?

// somefile.ts
interface Data {
    otherProperty: string;
}

// otherfile.ts
interface Data {
    name: string;
    value: number;
}

// mainfile.ts
type Constructor<T> = (P in T) => T;
type CreateData = Constructor<Data>; // ?

the order of declaration:

interface One {
   one: number;
}
interface Two extends One {
   two: string;
}
interface Three {
   three: boolean;
}
interface Four extends Three, Two {
}
type MakeFour = Contructor<Four>;
// same as
type MakeFour = (three: boolean, one: number, two: string) => Four

in you case it should be a type error since the order cannot be determined

Why not just make object spread types valid in argument positions (so the spread type flattens into part of the argument list)? I think that would solve this elegantly:

type Constructor<T> = (...T) => T;
interface Data {
    name: string;
    value: number;
}
type CreateData = Constructor<Data>;

It also makes it obvious how to combine a spread object with normal arguments, and removes a confusingly useless type parameter.

why not?

because using (...T) you can only do trivial mapping (property of some type to a parameter of exactly the same type), sure it will support this exact use case, but extrapolating the ideas of mapped type we might support more sophisticated use cases:

type Crazify<T> = (P in keyof T: MyCrazyParam<T[P]>) => MyEvenCrazierType<T>;

I don't know why we didn't decline this earlier. We can't take a reliance on property ordering.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

weswigham picture weswigham  ·  3Comments

dlaberge picture dlaberge  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

DanielRosenwasser picture DanielRosenwasser  ·  3Comments

siddjain picture siddjain  ·  3Comments