diegohaz / constate

React Context + State

Home Page:https://codesandbox.io/s/github/diegohaz/constate/tree/master/examples/counter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Better Typescript types

Linksku opened this issue · comments

I'm learning TS and spent a long time figuring out how to type Constate properly, turns out it wasn't possible in TS 3, I needed TS 4:

declare module 'constate' {
  function constate<
    StoreProps,
    StoreValue,
    SplitValue extends ((p: StoreValue) => any),
    SplitValues extends ((p: StoreValue) => any)[],
  >(
    useValue: (p: StoreProps) => StoreValue,
    splitValue: SplitValue,
    ...splitValues: SplitValues
  ): [
    React.FC<StoreProps>,
    () => ReturnType<SplitValue>,
    ...(SplitValues extends infer A
    ? {
      [K in keyof A]: () => (A[K] extends (...args: any) => infer R ? R : never);
    }
    : never),
  ];

  function constate<
    StoreProps,
    StoreValue,
  >(useValue: (p: StoreProps) => StoreValue): [
    React.FC<StoreProps>,
    () => StoreValue,
  ];

  export default constate;
}

Since TS 4 is still in beta, this shouldn't be included in Constate yet, but I thought I'd share. Let me know if there's anything that can be improved!

commented

The library is already written in TypeScript. Ideally, you shouldn't do anything do get types working. Isn't it working for you?

With the built-in types, it doesn't infer much:

const [CounterProvider, useCount] = constate(
  function useCounter() {
    const [count, setCount] = React.useState(0);
    return { count };
  },
  useCounter,
  value => value.count,
);

typeof useCount; // default: () => any, mine: () => number
commented

@Linksku You're not using the function correctly. Please, take a look at the README again.

This is working as expected:
Screenshot of typescript code with correct behavior

commented

But I agree that it will be much better with TS 4 spreads. And it'll hopefully fix #109.

Hmm it does work after I remove my type, not sure what I did wrong initially, thanks!