From 1c322a03363f808a50e8ed2f3aea471a8ae307bf Mon Sep 17 00:00:00 2001 From: Igor Korolev Date: Sun, 11 Nov 2018 01:51:40 +0400 Subject: [PATCH 1/2] Enable no-implicit-any for typechecks --- test/typecheck.createLogic.ts | 6 +++--- tsconfig.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/typecheck.createLogic.ts b/test/typecheck.createLogic.ts index 0ef1fdc..5dd2f46 100644 --- a/test/typecheck.createLogic.ts +++ b/test/typecheck.createLogic.ts @@ -182,7 +182,7 @@ import { Dependency, Meta, Payload, State } from './typecheck'; dispatchReturn: true, successType: 'successType' }, - process({ getState, action, cancelled$ }): void { + process({ getState, action, cancelled$ }: { getState: any, action: any, cancelled$: any }): void { let state: State = getState(); let expectedAction: | (StandardAction<'type'>) @@ -202,7 +202,7 @@ import { Dependency, Meta, Payload, State } from './typecheck'; dispatchReturn: true, successType: (payload: Payload) => ({ type: 'successType' }) }, - process({ getState, action, cancelled$ }) { + process({ getState, action, cancelled$ }: { getState: any, action: any, cancelled$: any }) { let state: State = getState(); let expectedAction: | (ActionBasis<'type'> & PayloadBasis & MetaBasis) @@ -218,7 +218,7 @@ import { Dependency, Meta, Payload, State } from './typecheck'; dispatchReturn: true, dispatchMultiple: false }, - process(depObj) { + process(depObj: any) { let dep: Dependency = depObj; let state: State = depObj.getState(); let expectedAction: (ActionBasis<'type'>) | ErroneousAction<'type'> = diff --git a/tsconfig.json b/tsconfig.json index 19d25ee..3b6edcd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "moduleResolution": "node", "esModuleInterop": true, "noEmit": true, - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitUseStrict": false, "noLib": false, "noResolve": false, From a4390ff3cb814ffe5a508e744fa0fce9d216a3cd Mon Sep 17 00:00:00 2001 From: Igor Korolev Date: Sun, 11 Nov 2018 15:42:58 +0400 Subject: [PATCH 2/2] Derive types for transform/process/validate hooks When the 'type' for createLogic is an action creator, we can see what it's returning and derive the type of the action for the hooks later. --- definitions/logic.d.ts | 44 +++++++++++++++++------------------ test/typecheck.createLogic.ts | 27 +++++++++++++++++++++ 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/definitions/logic.d.ts b/definitions/logic.d.ts index f4e31c6..aee0bbf 100644 --- a/definitions/logic.d.ts +++ b/definitions/logic.d.ts @@ -67,11 +67,12 @@ export interface CreateLogic { Meta extends Object = undefined, Dependency extends object = {}, Context extends Object = undefined, - Type extends string = string + Type extends string = string, + Action extends StandardAction = StandardAction, >( config: CreateLogic.Config< State, - Action, + Action, Dependency, Context, Type @@ -84,11 +85,12 @@ export interface CreateLogic { Payload extends Object = undefined, Meta extends Object = undefined, Dependency extends object = {}, - Type extends string = string + Type extends string = string, + Action extends StandardAction = StandardAction, >( config: CreateLogic.Config< State, - Action, + Action, Dependency, undefined, Type @@ -100,23 +102,25 @@ export interface CreateLogic { State extends object, Dependency extends object = {}, Context extends Object = undefined, - Type extends string = string + Type extends string = string, + Action extends StandardAction = StandardAction >( - config: CreateLogic.Config, Dependency, Context, Type> + config: CreateLogic.Config ): Logic; // createLogic with State and Type only - ( - config: CreateLogic.Config, {}, undefined, Type> + = StandardAction>( + config: CreateLogic.Config ): Logic; // createLogic with State, Dependency and Type only < State extends object, Dependency extends object = {}, - Type extends string = string + Type extends string = string, + Action extends StandardAction = StandardAction >( - config: CreateLogic.Config, Dependency, undefined, Type> + config: CreateLogic.Config ): Logic; } @@ -142,6 +146,11 @@ export namespace CreateLogic { action$: Observable; }; + export type ActionCreatorType = { + (payload: PayloadExtractor): Action; + toString(): string; + } + export type PrimitiveType = | Type | RegExp @@ -168,7 +177,7 @@ export namespace CreateLogic { Type extends string > { name?: string | Function; - type: TypeMatcher>; + type: TypeMatcher> | ActionCreatorType; cancelType?: TypeMatcher>; latest?: boolean; debounce?: number; @@ -253,9 +262,7 @@ export namespace CreateLogic { Context extends Object = undefined > { processOptions?: Process.Options; - process?: - | Process.SimpleHook - | Process.AdvancedHook; + process?: Process.Hook; } export namespace Process { @@ -276,14 +283,7 @@ export namespace CreateLogic { ctx: Context; }; - export type SimpleHook< - State extends object, - Action extends StandardAction, - Dependency extends object, - Context extends Object = undefined - > = (depObj: Process.DepObj) => void; - - export type AdvancedHook< + export type Hook< State extends object, Action extends StandardAction, Dependency extends object, diff --git a/test/typecheck.createLogic.ts b/test/typecheck.createLogic.ts index 5dd2f46..53b5a4c 100644 --- a/test/typecheck.createLogic.ts +++ b/test/typecheck.createLogic.ts @@ -280,6 +280,33 @@ import { Dependency, Meta, Payload, State } from './typecheck'; }); } +{ + interface ActionCreator

{ + (payload: P): { type: string; payload: P }; + toString(): string; + } + let fooAction: ActionCreator<{ foo: number }>; + const logic1 = createLogic({ + type: fooAction, + validate({action}) { + action.payload.foo.toFixed(); + }, + }); + const logic2 = createLogic({ + type: fooAction, + process({ action }) { + action.payload.foo.toExponential(); + }, + }); + const logic3 = createLogic({ + type: fooAction, + process({ action }, dispatch, done) { + action.payload.foo.toExponential(); + }, + }) +} + + // // EXPECT ERROR //