Skip to content

type transformation for mapping object properties to function parameters #12265

Description

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;

Activity

  1. gcnew commented on Nov 15, 2016

    @gcnew
    Contributor

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

    • ADT constructors
    • bind / apply
  2. aluanhaddad commented on Nov 16, 2016

    @aluanhaddad
    Contributor

    This is really interesting

  3. dsherret commented on Nov 16, 2016

    @dsherret
    Contributor

    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>; // ?
  4. zpdDG4gta8XKpMCd commented on Nov 16, 2016

    @zpdDG4gta8XKpMCd
    Author

    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
    
  5. zpdDG4gta8XKpMCd commented on Nov 16, 2016

    @zpdDG4gta8XKpMCd
    Author

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

  6. weswigham commented on Nov 19, 2016

    @weswigham
    Member

    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.

  7. zpdDG4gta8XKpMCd commented on Nov 20, 2016

    @zpdDG4gta8XKpMCd
    Author

    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>;
    
  8. RyanCavanaugh commented on Jul 21, 2020

    @RyanCavanaugh
    Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions