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

Type error when using created selectors as input for a new selector. #237

Closed
cyr-x opened this issue Mar 28, 2017 · 9 comments
Closed

Type error when using created selectors as input for a new selector. #237

cyr-x opened this issue Mar 28, 2017 · 9 comments

Comments

@cyr-x
Copy link

cyr-x commented Mar 28, 2017

After the upgrade to version 3.0.0 the typescript compiler complains about a non matching argument type. Using the following code:

export const selectProductStore = (state: any): State => state.productStore;
export const getEntity = createSelector(selectProductStore, store => store.entity);
export const getTitle = createSelector(getEntity, entity => entity.title);

Is producing the following error:

Argument of type 'OutputSelector<any, Product, (res: State) => Product>' is not assignable to parameter of type '[ParametricSelector<{}, {}, {}>, ...'. 
Property '0' is missing in type  'OutputSelector<any, Product, (res: State) => Product>'

The same code doesn't show any typing error with version 2.5.4.

@alex3165
Copy link
Contributor

I noticed it as well, would be nice to add your example to https://github.com/reactjs/reselect/blob/master/typescript_test/test.ts so that we handle this use case in the typescript test and fix it. I think that is because Selector is not the same type as OutputSelector so one fix would be to only use OutputSelector everywhere and put resultFunc , recomputations and resetRecomputations Optional, @aikoven what do you think about it ?

@alex3165
Copy link
Contributor

I tried to reproduce your issue but didn't get any error : alex3165@388da06#diff-2fe2e76dc80d303b543f572094baf958R35

@cyr-x
Copy link
Author

cyr-x commented Mar 29, 2017

The strange thing is the code compiles fine and runs without errors, just the editor is showing the error and therefore autocompletion is broken. I tried sublime and atom both showing this error when hovering over getEntity.

@alex3165
Copy link
Contributor

@kevinwardenga It is probably because your IDE is using an old version of Typescript

@cyr-x
Copy link
Author

cyr-x commented Mar 29, 2017

I've already checked that, it's using the latest typescript version (2.2.2).

Also the following type declarations are showing an error:

export type Selector<S, R> = (state: S) => R;
export interface OutputSelector<S, R, C> extends Selector<S, R> {
  resultFunc: C;
  recomputations: () => number;
  resetRecomputations: () => number;
}

export type ParametricSelector<S, P, R> = (state: S, props: P, ...args: any[]) => R;
export interface OutputParametricSelector<S, P, R, C> extends ParametricSelector<S, P, R> {
  resultFunc: C;
  recomputations: () => number;
  resetRecomputations: () => number;
}

which says:

An interface may only extend a class or another interface.

for extends Selector and extends ParametricSelector

Update:
After changing Selector and ParametricSelector from type to an interface the errors are gone and everything is working as expected.

export interface Selector<S, R> {
  (state: S): R;
}
export interface OutputSelector<S, R, C> extends Selector<S, R> {
  resultFunc: C;
  recomputations: () => number;
  resetRecomputations: () => number;
}

export interface ParametricSelector<S, P, R> {
  (state: S, props: P, ...args: any[]): R
}
export interface OutputParametricSelector<S, P, R, C> extends ParametricSelector<S, P, R> {
  resultFunc: C;
  recomputations: () => number;
  resetRecomputations: () => number;
}

@aikoven
Copy link
Contributor

aikoven commented Mar 30, 2017

After changing Selector and ParametricSelector from type to an interface the errors are gone and everything is working as expected.

As far as I remember, extending type alias was an error before. Although, latest TypeScript doesn't give me any error. Maybe your editor uses some built-in TypeScript compiler that is outdated.

Either way, I've created a PR #240 that replaces type aliases with interfaces. I also added a test for nested selectors.

@cyr-x
Copy link
Author

cyr-x commented Mar 30, 2017

@aikoven you're right it's possible since version 2.2, i know managed to get sublime to recognize the local typescript version, had do reinstall the typescript package and now it's properly using version 2.2 and all errors are gone. But it should be good to note in the docs that you need typescript version 2.2.x to use this package or use interfaces instead of types like in your pull request.

@aikoven
Copy link
Contributor

aikoven commented Mar 30, 2017

@kevinwardenga I don't see any reason to constraint version of TS since there are no other features that require latest.

@cyr-x
Copy link
Author

cyr-x commented Mar 30, 2017

@aikoven yep when your pull request is getting merged there's no need to contraint the TS version.

@cyr-x cyr-x closed this as completed Mar 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants