wip w/ aotds

typescript
Yanick Champoux 2021-10-14 12:30:06 -04:00
parent 8c026314f5
commit 33ded1448e
5 changed files with 126 additions and 99 deletions

View File

@ -40,7 +40,7 @@
"typescript": "^4.4.3"
},
"license": "MIT",
"main": "dist/index.js",
"main": "src/index.js",
"name": "updux",
"description": "Updeep-friendly Redux helper framework",
"scripts": {

26
types/actions.d.ts vendored Normal file
View File

@ -0,0 +1,26 @@
export type ActionGenerator<TType extends string = string, TPayloadGen = undefined> = {
type: TType;
} & (TPayloadGen extends Function
? (...args: Parameters<TPayloadGen>) => {
type: TType;
payload: ReturnType<TPayloadGen>;
}
: (...args: any[]) => { type: TType; payload?: unknown });
interface Action {
<T extends string = string>(actionType: T): ActionGenerator<T>;
<T extends string = string, F extends Function = Function>(
actionType: T,
payloadGen: F
): ActionGenerator<T, F>;
}
/**
* Creates an action generator.
*/
export const action: Action;
/**
* Utility type for payload generators that are passthroughs.
*/
export type Payload<T = unknown> = (arg: T) => T;

182
types/index.d.ts vendored
View File

@ -5,107 +5,95 @@ type Mutation<TState = unknown> = (
action: Record<string, unknown>
) => (state: TState) => TState;
type ActionGenerator = { type: string } & ((...args: any[]) => {
type: string;
payload?: unknown;
});
export * from './actions';
declare module 'updux' {
/**
* Configuration object typically passed to the constructor of the class Updux.
*/
export interface UpduxConfig<TState = unknown> {
/**
* Configuration object typically passed to the constructor of the class Updux.
* Local initial state.
* @default {}
*/
export interface UpduxConfig<TState = unknown> {
/**
* Local initial state.
* @default {}
*/
initial?: TState;
/**
* Subduxes to be merged to this dux.
*/
subduxes?: Dict<Updux | UpduxConfig>;
/**
* Local actions.
*/
actions?: Record<string, any>;
/**
* Local selectors.
*/
selectors?: Record<string, Function>;
/**
* Local mutations
*/
mutations?: Record<string, Function>;
/**
* Selectors to apply to the mapped subduxes. Only
* applicable if the dux is a mapping dux.
*/
mappedSelectors?: Record<string, Function>;
/**
* Local effects.
*/
effects?: Record<string, Function>;
/**
* Local reactions.
*/
reactions?: Record<string, Function>;
/**
* If true, enables mapped reactions. Additionally, it can be
* a reaction function, which will treated as a regular
* reaction for the mapped dux.
*/
mappedReaction?: Function | boolean;
}
export class Updux<TState = unknown> {
constructor(config: Partial<UpduxConfig<TState>>);
get initial(): TState;
get selectors(): unknown;
/**
* Sets the local mutation for the given action.
*
* The action can be specified via its type
* or its generator.
*
* Returns the same mutation function.
*/
setMutation<TMutation extends Mutation>(
actionType: string,
mutation: TMutation
): TMutation;
setMutation<TMutation extends Mutation>(
action: ActionGenerator,
mutation: TMutation
): TMutation;
/**
* Registers the action for the dux.
* If no payload function is provided, whatever is
* given as an argument to the action generator will
* be set as-is in the action's payload.
*/
setAction(actionType: string, payloadFunc?: Function);
/**
* Registers a selector for the dux.
*/
setSelector(name: string, selector: Selector);
}
initial?: TState;
/**
* Creates an action generator.
* Subduxes to be merged to this dux.
*/
export function action(
actionType: string,
payloadFunction?: Function
): ActionGenerator;
subduxes?: Dict<Updux | UpduxConfig>;
/**
* Local actions.
*/
actions?: Record<string, any>;
/**
* Local selectors.
*/
selectors?: Record<string, Function>;
/**
* Local mutations
*/
mutations?: Record<string, Function>;
/**
* Selectors to apply to the mapped subduxes. Only
* applicable if the dux is a mapping dux.
*/
mappedSelectors?: Record<string, Function>;
/**
* Local effects.
*/
effects?: Record<string, Function>;
/**
* Local reactions.
*/
reactions?: Record<string, Function>;
/**
* If true, enables mapped reactions. Additionally, it can be
* a reaction function, which will treated as a regular
* reaction for the mapped dux.
*/
mappedReaction?: Function | boolean;
}
export class Updux<TState = unknown> {
constructor(config: Partial<UpduxConfig<TState>>);
get initial(): TState;
get selectors(): unknown;
/**
* Sets the local mutation for the given action.
*
* The action can be specified via its type
* or its generator.
*
* Returns the same mutation function.
*/
setMutation<TMutation extends Mutation>(
actionType: string,
mutation: TMutation
): TMutation;
setMutation<TMutation extends Mutation>(
action: ActionGenerator,
mutation: TMutation
): TMutation;
/**
* Registers the action for the dux.
* If no payload function is provided, whatever is
* given as an argument to the action generator will
* be set as-is in the action's payload.
*/
setAction(actionType: string, payloadFunc?: Function);
/**
* Registers a selector for the dux.
*/
setSelector(name: string, selector: Selector);
}

View File

@ -1,6 +1,6 @@
import { printType, expectAssignable, expectType } from 'tsd';
import { Updux } from '.';
import { Updux, ActionGenerator, action } from '.';
const dux = new Updux({});
expectType<unknown>( dux.initial );
@ -12,3 +12,16 @@ expectType<unknown>( dux.initial );
expectAssignable<{initial: {a:string}}>(dux);
}
// ActionGenerator
() => {
let a = action('a');
expectAssignable<{type: string}>(a);
expectAssignable<() => {payload?: unknown}>(a);
let b = action('b', (() => ({})) as unknown as (name: string) => { name: string } );
const c = b("foo");
expectAssignable<{payload: { name: string } }>(c);
}

View File