Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow type parameter constraints to reference other type parameters #2304

Closed
NN--- opened this issue Mar 11, 2015 · 5 comments
Closed

Allow type parameter constraints to reference other type parameters #2304

NN--- opened this issue Mar 11, 2015 · 5 comments
Assignees
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@NN---
Copy link

NN--- commented Mar 11, 2015

I would like to have some feature that infers any possible types from the given object in the generic function.
For instance I have a function that receives Object, and I want to have a more specific callback than 'any'.
Current code:

function a(obj: Object, f: (value: any) => any) {
 for(var p in obj) if(obj.hasOwnProperty(p)) {
  (<any>obj)[p] = f((<any>obj)[p]) 
 }
}

a({x:1}, (value: any) => (<number>value)+1);

I wish I had something with more strict typing.

function a<T extends Object, Value: union_of_properties_types_of(T)>(obj: T, f: (value: Value) => Value) {
 for(var p in obj) if(obj.hasOwnProperty(p)) {
  (<any>obj)[p] = f(<Value>(<any>obj)[p]) 
 }
}

// 'f' is denoted to number => number
a({x:1}, value => value+1);

// 'f' is string => string
a({x:"x", y:"y"}, value => {
 return value+"z";
});
@danquirk
Copy link
Member

If we allowed type parameter constraints to reference other type parameters this signature might get you what you wanted:

function a<PropType, T extends { [idx:string]: PropType }>(obj: T, f: (value: PropType) => PropType) { .. }

@NN---
Copy link
Author

NN--- commented Mar 12, 2015

If PropType will be a union type, then yes.

@mhegazy mhegazy added the Suggestion An idea for TypeScript label Mar 24, 2015
@danquirk danquirk changed the title More specific type for object in generic function Allow type parameter constraints to reference other type parameters Apr 6, 2015
@jbrantly
Copy link

I wanted to give another example for where this would come in useful in the React bindings.

React has an API that looks like createElement(componentType, props). The type of props is specific to the componentType being used. Today this is modeled with:

createElement<P>(type: { new(): Component<P> }, props: P): ReactElement<P>

However, in actuality there is an implicit prop called ref that can be used on any component. This prop is a function whose single argument is an instance of the component. This could be modeled with:

createElement<P, C extends Component<P>>(type: { new(): C }, props: P & { ref: (component: C) => any }): ReactElement<P>

However, the above isn't currently allowed due to this issue. Ideally not only would the above be allowed but also have the type arguments inferred from usage.

@RyanCavanaugh RyanCavanaugh added the In Discussion Not yet reached consensus label Oct 19, 2015
@RyanCavanaugh RyanCavanaugh added Committed The team has roadmapped this issue and removed In Discussion Not yet reached consensus labels Nov 2, 2015
@RyanCavanaugh
Copy link
Member

@ahejlsberg is going to see what would be involved in removing the restriction. It may be as simple as removing the error, or there may be deeper problems with circularity that motivated this back in the Ye Olde Compiler days.

@DeadMG
Copy link

DeadMG commented Nov 25, 2015

I would really like this as well for strongly typing a function that can merge properties, e.g. _.extends. The intersection syntax can correctly tell the compiler the return type of the function, but it can't infer types for the properties of the arguments that also exist on T. Having T extend U would be sufficient I think. React's setState is another example of a function that merges two objects that can't really be properly typed- the only solution we have so far is to make every property optional and then take T.

@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Dec 11, 2015
@mhegazy mhegazy added this to the TypeScript 1.8 milestone Dec 11, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

7 participants