-
Notifications
You must be signed in to change notification settings - Fork 77
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
typescript type support #79
Comments
If @didierfranc isn't planning on updating typings with every release it might be better to move them to https://github.com/DefinitelyTyped/DefinitelyTyped |
We're halfway there, but there's some work to be done. Especially with the prop-type of the consuming components. declare module "react-waterfall" {
import { Config, Store } from "react-waterfall/types";
const rw: ReactWaterfall;
interface ReactWaterfall {
<S, A>(config: Config<S, A>, middlewares?: any[]): Store<S, A>;
}
export = rw;
}
declare module "react-waterfall/types" {
import * as React from "react";
export type Config<S, A> = {
initialState: S,
actionsCreators: {
[K in keyof A]: (state: S, actions: A, ...args: any[]) => Partial<S> | Promise<Partial<S>>
}
}
export type Connect<S> = (selector: (state: S) => any) => (baseComponent: React.ComponentType<any>) => React.ComponentType<any>
export type Store<S, A> = {
Provider: any,
connect: Connect<S>,
actions: A,
subscribe: any,
unsubscribe: any,
}
} Note that we had to separate the types in a different namespace and overwrite the export, because of the way react-waterfall does its export. @chrismcleod Do you guys have any suggestions? |
Yep I definitely would like to contribute @SaphuA. I'll try to allocate some time within this week if someone else is faster please indicate 🍻 - appreciated! |
Alright I finally had to chance to look at it (sorry for the delay!). This is what I came up with based on @SaphuA s great work. Notable extensions: Strong typing for the component (i.e., TS will ensure that you really "connect" to the state also from a typings perspective). Less use of declare module 'react-waterfall' {
import { Config, Store } from 'react-waterfall/types';
const rw: ReactWaterfall;
interface ReactWaterfall {
<S, A>(config: Config<S, A>, middlewares?: any[]): Store<S, A>;
}
export default rw;
}
declare module 'react-waterfall/types' {
import * as React from 'react';
type RemoveArgumentTypes<S, A, T> = T extends (state: S, actions: A, ...args: infer U) => infer R ? U : any;
export interface Config<S, A> {
initialState: S;
actionsCreators: { [K in keyof A]: (state: S, actions: A, ...args: any[]) => Partial<S> | Promise<Partial<S>> };
}
export interface Connect<S> {
<P, K>(selector: (state: S) => K): (baseComponent: React.ComponentType<P & K>) => React.ComponentType<P>;
}
export type Store<S, A> = {
Provider: React.ComponentType;
connect: Connect<S>;
actions: { [K in keyof A]: (...a: RemoveArgumentTypes<S, A, A[K]>) => void };
subscribe: any;
unsubscribe: any;
};
} It's not completely finished. I'll update the post once I have it in a state that I'm satisfied with. Question though @didierfranc: Should the d.ts be part of this repo or is an "@types/" publication the new preference? Personally, I would love to have them in here - but I do of course understand the maintenance argument. |
How do u use these types? I've tried and it failed on actual store creation. |
@DimitryDushkin not sure what failed without some example code. Just place the snippet above in a d.ts file in repository (e.g., in src/modules.d.ts). I think something like the following should work (just took the standard example and added some types for being explicit - note: many of them may be omitted / are inferred in practice): import createStore from 'react-waterfall';
export interface State {
count: 0;
}
const initialState: State = { count: 0 };
export const { Provider, connect, actions } = createStore({
initialState,
actionsCreators: {
increment({ count }: State): Partial<State> {
return { count: count + 1 };
},
},
}); Note that I am missing in the config directly in the store - that way you ensure that TS correctly infers the type. Otherwise it needs to infer it from some variable directly, which may not work reliably depending on the conditions. |
@FlorianRappl the RemoveArgumentTypes with infer is pretty brilliant! Great job. Small improvement to change: |
@FlorianRappl what type will be in second argument of action? I mean export const { Provider, connect, actions } = createStore({
initialState,
actionsCreators: {
increment({ count }: State, actions: ???): Partial<State> {
return { count: count + 1 };
},
},
}); Also looks like actions: { [K in keyof A]: (...a: RemoveArgumentTypes<S, A, A[K]>) => void }; is not quite correct, it should be more like actions: { [K in keyof A]: (...a: RemoveArgumentTypes<S, A, A[K]>) => ReturnType<A[K]> }; but still type of arguments of actions is any. I'm trying to resolve it. |
any update on this issue? I saw that there's no published type on definitelytyped do you still need help with this? |
I've made quite similar library — https://github.com/DimitryDushkin/react-localux — it is written on TS and have thunk-like functionality built-in. That's some kind of update.) |
I've modified the above to fix some of the type issues that I was having. Along with defining your own typeRoots, you'll need to add a paths variable pointing to your typings root.
If I have time I'll try to fix the actions typings |
I think it is impossible to fix it. Basically you want something like: type ExportedAction<F extends Function> = F extends (
...args: infer Args
) => (actions: any) => infer R
? (...args: Args) => R
: never;
type StrippedActions<A extends Record<string, Function>> = {
[K in keyof A]: ExportedAction<A[K]>
};
const exampleActions = {
action: (arg: string) => (
actions: StrippedActions<typeof exampleActions>
) => {
actions.action("op");
return "op";
}
};
const s = createStore(state, exampleActions); Which is fine, but looks like it is impossible to write it without explicitly write every action like const exampleActions: SomeType<typeof exampleActions> = {...} |
Hey :) What is the current status of adding types to react-waterfall? Would you need some help? I would love to try adding some types with some guidance. |
It would be great to have a type definition file for the project!
The text was updated successfully, but these errors were encountered: