From 27958a6d14af7654b7b70fba68383c3458db56cd Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Mon, 18 Oct 2021 08:46:00 -0400 Subject: [PATCH] add generic initial --- Taskfile.yml | 7 +++++++ src/Updux.ts | 22 ++++++++++++++++------ src/actions.test.js | 2 +- src/{initial.test.js => initial.test.ts} | 0 src/types.ts | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+), 7 deletions(-) rename src/{initial.test.js => initial.test.ts} (100%) diff --git a/Taskfile.yml b/Taskfile.yml index 906bf7c..05923f2 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -6,6 +6,13 @@ vars: GREETING: Hello, World! tasks: + tsc: tsc + test: jest + + check: + deps: [tsc, test] + + 'test:types': tsd docs: cmds: diff --git a/src/Updux.ts b/src/Updux.ts index 82b0d88..9ba43f3 100644 --- a/src/Updux.ts +++ b/src/Updux.ts @@ -14,12 +14,17 @@ import { augmentMiddlewareApi, } from './buildMiddleware'; -import { Dict } from './types'; +import { AggregateDuxState, Dict } from './types'; /** * Configuration object typically passed to the constructor of the class Updux. */ -export interface UpduxConfig { +export interface UpduxConfig< + TState = any, + TActions = {}, + TSelectors = {}, + TSubduxes = {}, +> { /** * Local initial state. * @default {} @@ -29,7 +34,7 @@ export interface UpduxConfig { /** * Subduxes to be merged to this dux. */ - subduxes?: Dict; + subduxes?: TSubduxes; /** * Local actions. @@ -70,7 +75,12 @@ export interface UpduxConfig { mappedReaction?: Function | boolean; } -export class Updux { +export class Updux< + TState extends any = {}, + TActions = {}, + TSelectors = {}, + TSubduxes extends object = {}, +> { /** @type { unknown } */ #initial = {}; #subduxes = {}; @@ -84,7 +94,7 @@ export class Updux { #mappedSelectors = undefined; #mappedReaction = undefined; - constructor(config: UpduxConfig) { + constructor(config: UpduxConfig) { this.#initial = config.initial ?? {}; this.#subduxes = config.subduxes ?? {}; @@ -148,7 +158,7 @@ export class Updux { } /** @member { unknown } */ - get initial() { + get initial() : AggregateDuxState { return this.#memoInitial(this.#initial, this.#subduxes); } diff --git a/src/actions.test.js b/src/actions.test.js index 094ac1a..0351891 100644 --- a/src/actions.test.js +++ b/src/actions.test.js @@ -1,4 +1,4 @@ -import { action } from './actions.js'; +import { action } from './actions'; test('action generators', () => { const foo = action('foo'); diff --git a/src/initial.test.js b/src/initial.test.ts similarity index 100% rename from src/initial.test.js rename to src/initial.test.ts diff --git a/src/types.ts b/src/types.ts index 8cfddb8..8ca01f7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,2 +1,20 @@ export type Dict = Record; + +type Subdux = { + initial: TState +}; + +type StateOf = D extends { initial: infer I } ? I : unknown; + +type Subduxes = Record; + +export type DuxStateSubduxes = C extends { '*': infer I } + ? { + [key: string]: StateOf; + [index: number]: StateOf; + } + : { [K in keyof C]: StateOf }; + +export type AggregateDuxState = TState & DuxStateSubduxes; +