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

Better Typescript types #117

Closed
Linksku opened this issue Aug 18, 2020 · 5 comments · Fixed by #118
Closed

Better Typescript types #117

Linksku opened this issue Aug 18, 2020 · 5 comments · Fixed by #118

Comments

@Linksku
Copy link

Linksku commented Aug 18, 2020

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!

@diegohaz
Copy link
Owner

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

@Linksku
Copy link
Author

Linksku commented Aug 18, 2020

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

@diegohaz
Copy link
Owner

@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

@diegohaz
Copy link
Owner

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

@Linksku
Copy link
Author

Linksku commented Aug 19, 2020

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

@Linksku Linksku closed this as completed Aug 19, 2020
diegohaz added a commit that referenced this issue Sep 8, 2020
Closes #109
Closes #117

BREAKING CHANGE: Types now depend on TypeScript v4.0.

BREAKING CHANGE: The deprecated function/object API has been removed.

  **Before**:
  ```jsx
  import createUseContext from "constate";
  const useCounterContext = createUseContext(useCounter);
  <useCounterContext.Provider>
    ...
  </useCounterContext.Provider>
  ```

  **After**:
  ```jsx
  import constate from "constate";
  const [CounterProvider, useCounterContext] = constate(useCounter);
  <CounterProvider>
    ...
  </CounterProvider>
  ```
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

Successfully merging a pull request may close this issue.

2 participants