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

Inferring types: curried vs not curried #15005

Closed
wclr opened this issue Apr 4, 2017 · 4 comments
Closed

Inferring types: curried vs not curried #15005

wclr opened this issue Apr 4, 2017 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@wclr
Copy link

wclr commented Apr 4, 2017

TypeScript Version: 2.2.2

This possible typings of props function from ramda for two arguments:

I wonder why if second object argument is not curried TS can not infer types in results:

declare function props<P1 extends string, P2 extends string, T1, T2>
  (ps: [P1, P2], obj: {[K in P1]: T2} & {[K in P2]: T2}): [T1, T2];

props(['a', 'b'], {a: 1, b: '2'})[0] => // can not infer `number` type
props(['a', 'b'], {a: 1, b: '2'})[1] => // can not infer `string` type

And when curried it can:

// this is inferred
declare function props<P1 extends string, P2 extends string>
  (ps: [P1, P2]): <T1, T2>(obj: {[K in P1]: T1} & {[K2 in P2]: T2}) 
  => [T1, T2];

props(['a', 'b'])({a: 1, b: '2'})[0] => // this can infer `number` type
props(['a', 'b'])({a: 1, b: '2'})[1] => // this can infer `string` type

Is TS going to make it work in future?

@PyroVortex
Copy link

Type inference will also work with this declaration:

declare function props<P1 extends string, P2 extends string, O extends {[K in P1 | P2]: any}>
  (ps: [P1, P2], obj: O): [O[P1], O[P2]];

In your first example, the mapped types for obj are additional inference sites for P1 and P2, which results in them being both inferred as 'a' | 'b'. In the curried case, P1 and P2 are fixed as 'a' and 'b', respectively, when the second function gets called, and therefore limit what each of the two intersected types matches.

@wclr
Copy link
Author

wclr commented Apr 5, 2017

@PyroVortex
Is it possible for this case to limit ps tuple size to 2? Or prohibit props that are not in obj

So it wouldn't allow:

// should be an error, as 'whatever' is not in {a: 1, b: '2'}`
props(['a', 'b', 'whatever'])({a: 1, b: '2'})[0] 

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label May 24, 2017
@raveclassic
Copy link

raveclassic commented Oct 17, 2018

I run into similar problem:

declare const a: { cb: (arg: number) => void }

declare function test1<T>(a: T, b: T): void;
test1(a, { cb(arg) { } }) // parameter 'arg' implicitly has an 'any' type

declare function test2<T>(a: T, b: () => T): void;
test2(a, () => ({ cb(arg) { } })) // parameter 'arg' implicitly has an 'any' type

declare function test3<T>(a: T): (b: T) => void // curried
test3(a)({ cb(arg) { } }) // (parameter) arg: number

declare function test4<T>(a: T): (b: () => T) => void // curried
test4(a)(() => ({ cb(arg) { } })) // (parameter) arg: number

Looks like there're some related issues: #23429, #22715 #25092

raveclassic added a commit to devexperts/dx-platform that referenced this issue Oct 17, 2018
* feat(react-kit): accept defaultProps in withrx selector result

This allows to pass handlers along with props in WithRXSelector

BREAKING CHANGE: 
- `defaultProps` argument is moved to `WithRXSelectorResult`; 
- `static defaultProps` property is removed; 
- `props$` stream passed to `selector` doesn't contain fields from `defaultProps` anymore
- `withRX` now accepts `Target` separately for better type inference in `props`/`defaultProps`

* chore(react-kit): update with-rx typechecking test

* chore(react-kit): make withRX curried for better type inference microsoft/TypeScript#15005 (comment)
@RyanCavanaugh RyanCavanaugh added Question An issue which isn't directly actionable in code and removed Needs Investigation This issue needs a team member to investigate its status. labels Sep 16, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants