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

createListSelector and createMapSelector are missing from typescript definitions #14

Open
pbadenski opened this issue Jan 11, 2019 · 2 comments

Comments

@pbadenski
Copy link

No description provided.

@heyimalex
Copy link
Owner

heyimalex commented Jan 12, 2019

When we created the original typings it wasn't possible, but maybe that's changed. I spent twenty minutes thinking about it just now and didn't get anywhere, so if you need this implemented you should take a crack at it. Check #9 for details on how we generated the original types if you get that far. The crux is that you need to define a generic type that takes a mapping function and then returns itself.

I think it's possible if you're willing to annotate both types, and maybe you can use infer somehow to make that unnecessary. I kinda like playing solve-the-type-puzzle so I may get to this next week.

@heyimalex
Copy link
Owner

Here's an update:

Ideally the list and map selectors would be usable without specifying any generics.

import { List } from "immutable";
import { createListSelector } from "reselect-map";

type State = {
  items: List<number>;
  mul: number;
};

const selector = createListSelector(
  (state: State) => state.items,
  (state: State) => state.mul,
  (elem, mul) => `value is ${elem * mul}`
);
// The created selector's output type is inferred to be List<string>.

However, this doesn't look like it's possible. I can infer the element type from a specific mapable type, ie: List<E>, but inferring the return type looks like it can't be done as List<E>.map<T>'s return type is itself generic wrt to the return type of the mapper function T.

So we're going to have to specify some types. But we should be able to get away with only specifying one. This leads to more of a usability decision than a technical one, and really we're kind of going around the type system. But because we can't define the result type in terms of the combiner's return type, that's kinda a given anyway.

Anyway, the gist is that you need to annotate the return type of your first selector to Mapper<ElementType,FinalResultType> for lists and KeyMapper<ElementType,KeyType,FinalResultType> for maps. I've published a branch that has these changes for anyone interested. The final result is maybe more convoluted than it needs to be, but it looks like it works so I'm calling it a day.

I'm thinking of adding support directly for immutable.js, since that's how these selectors are usually used, but I'm not sure about the implications for importing (like whether the end user needs immutable js installed or else the regular typings won't work at all). More work to come...

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

2 participants