diff --git a/devtools.d.ts b/devtools.d.ts new file mode 100644 index 0000000..c1ea60b --- /dev/null +++ b/devtools.d.ts @@ -0,0 +1,4 @@ +declare module "unistore/devtools" { + import { Store } from "unistore"; + export default function devtools(store: Store): Store; +} diff --git a/devtools.js b/devtools.js index 6c6b2f1..98ea240 100644 --- a/devtools.js +++ b/devtools.js @@ -1,4 +1,4 @@ -module.exports = function unistoreDevTools(store) { +module.exports.default = function unistoreDevTools(store) { var extension = window.__REDUX_DEVTOOLS_EXTENSION__ || window.top.__REDUX_DEVTOOLS_EXTENSION__; var ignoreState = false; diff --git a/index.d.ts b/index.d.ts index 6e00233..a77340b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,29 +1,17 @@ -// T - Wrapped component props -// S - Wrapped component state -// K - Store state -// I - Injected props to wrapped component +declare module "unistore" { + export type Action = (state: TStoreState, ...args: TArgs) => Partial; + export type BoundAction = (...args: TArgs) => void; -export type Listener = (state: K, action?: Action) => void; -export type Unsubscribe = () => void; -export type Action = (state: K, ...args: any[]) => void; -export type BoundAction = () => void; + export type Listener = (state: TStoreState, action?: Action) => void; + export type Unsubscribe = () => void; -export interface Store { - action(action: Action): BoundAction; - setState(update: object, overwrite?: boolean, action?: Action): void; - subscribe(f: Listener): Unsubscribe; - unsubscribe(f: Listener): void; - getState(): K; -} - -export default function createStore(state?: K): Store; - -export type ActionFn = (state: K) => object; + export interface Store { + action(action: Action): BoundAction; -export interface ActionMap { - [actionName: string]: ActionFn; + setState(update: object, overwrite?: boolean, action?: Action): void; + subscribe(func: Listener): Unsubscribe; + unsubscribe(func: Listener): void; + getState(): TStoreState; + } + export default function createStore(state?: TStoreState): Store; } - -export type ActionCreator = (store: Store) => ActionMap; - -export type StateMapper = (state: K, props: T) => I; diff --git a/preact.d.ts b/preact.d.ts index 9aa69d2..9da421b 100644 --- a/preact.d.ts +++ b/preact.d.ts @@ -1,22 +1,70 @@ -// T - Wrapped component props -// S - Wrapped component state -// K - Store state -// I - Injected props to wrapped component - declare module "unistore/preact" { import * as Preact from "preact"; - import { ActionCreator, StateMapper, Store } from "unistore"; + import { Store } from "unistore"; + + // Diff / Omit taken from https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-311923766 + type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T]; + type Omit = Pick>; + + export interface ProviderProps { + store: Store; + } + export class Provider, TStoreState> extends Preact.Component { + render(props: any, state: any): JSX.Element; + } + + //Props + + interface MapStateToProps { + (state: TStoreState, ownProps: TExternalProps): TStoreProps; + } + type MapStateToPropsParam = MapStateToProps | null | undefined; + + interface MapActionsToPropsFunction { + [actionName: string]: (state: TStoreState, ...args: any[]) => Partial; + } + interface MapActionsToPropsFactory { + (store: Store): TActionProps; + } + type MapActionsToPropsParam = MapActionsToPropsFactory; + + type DefaultMapActionToProps = { store: Store } - export function connect( - mapStateToProps: string | Array | StateMapper, - actions?: ActionCreator | object - ): (Child: (props: T & I) => Preact.VNode) => Preact.ComponentConstructor; + interface FunctionalComponent extends Preact.FunctionalComponent { } + interface Component extends Preact.ComponentConstructor { } + type AnyComponent = FunctionalComponent | Component; - export interface ProviderProps { - store: Store; + interface InferableComponentEnhancerWithProps { + ( + component: AnyComponent + ): Preact.FunctionalComponent & TNeedProps> & { WrappedComponent: Preact.FunctionalComponent } } - export class Provider extends Preact.Component, {}> { - render(props: ProviderProps, {}): Preact.VNode; + type InferableComponentEnhancer = InferableComponentEnhancerWithProps + + + export interface Connect { + (): InferableComponentEnhancer>; + + ( + mapStateToProps: MapStateToPropsParam + ): InferableComponentEnhancerWithProps, TExternalProps>; + + ( + mapStateToProps: T[] + ): InferableComponentEnhancerWithProps, TExternalProps>; + + ={}, TActionPropsRemap = { [K in keyof TActionProps]: (...args) => void }, TExternalProps={}, TStoreState={}>( + mapStateToProps: MapStateToPropsParam, + mapActionsToProps: MapActionsToPropsParam | TActionProps + ): InferableComponentEnhancerWithProps; + + ={}, TActionPropsRemap = { [K in keyof TActionProps]: (...args) => void }, TExternalProps={}, TStoreState={}>( + mapStateToProps: T[], + mapActionsToProps: MapActionsToPropsParam | TActionProps + ): InferableComponentEnhancerWithProps; + } + + export const connect: Connect; } diff --git a/react.d.ts b/react.d.ts index 113a729..65ba881 100644 --- a/react.d.ts +++ b/react.d.ts @@ -5,18 +5,66 @@ declare module "unistore/react" { import * as React from "react"; - import { ActionCreator, StateMapper, Store } from "unistore"; + import { Store } from "unistore"; - export function connect( - mapStateToProps: string | Array | StateMapper, - actions?: ActionCreator | object - ): (Child: (props: T & I) => React.ReactNode) => React.Component; + // Diff / Omit taken from https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-311923766 + type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T]; + type Omit = Pick>; - export interface ProviderProps { - store: Store; + export interface ProviderProps { + store: Store; } - - export class Provider extends Component, {}> { + export class Provider, TStoreState> extends React.Component { render(): React.ReactNode; } + + //Props + + interface MapStateToProps { + (state: TStoreState, ownProps: TExternalProps): TStoreProps; + } + type MapStateToPropsParam = MapStateToProps | null | undefined; + + interface MapActionsToPropsFunction { + [actionName: string]: (state: TStoreState, ...args: any[]) => Partial; + } + interface MapActionsToPropsFactory { + (store: Store): TActionProps; + } + type MapActionsToPropsParam = MapActionsToPropsFactory; //| MapActionsToPropsFunction; + + type DefaultMapActionToProps = { store: Store } + + interface FunctionalComponent extends React.StatelessComponent { } + interface Component extends React.Component { } + type AnyComponent = FunctionalComponent | Component; + + interface InferableComponentEnhancerWithProps { + ( + component: AnyComponent + ): FunctionalComponent & TNeedProps> & { WrappedComponent: AnyComponent } + } + + type InferableComponentEnhancer = InferableComponentEnhancerWithProps + + + export interface Connect { + (): InferableComponentEnhancer>; + + ( + mapStateToProps: MapStateToPropsParam + ): InferableComponentEnhancerWithProps, TExternalProps>; + + ( + mapStateToProps: T[] + ): InferableComponentEnhancerWithProps, TExternalProps>; + + ={}, TActionPropsRemap = { [K in keyof TActionProps]: (...args) => void }, TExternalProps={}, TStoreState={}>( + mapStateToProps: MapStateToPropsParam, + mapActionsToProps: MapActionsToPropsParam + ): InferableComponentEnhancerWithProps; + + } + + export const connect: Connect; }