From 0c0240f1855b376a4f2f4523ac8fc3b9b8d5f7b7 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 6 Apr 2021 14:02:15 -0700 Subject: [PATCH 1/2] test: typescript --- package.json | 4 +++- test-typescript.ts | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test-typescript.ts diff --git a/package.json b/package.json index c160182..fcf2830 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "types": "./index.d.ts", "scripts": { "build": "tsc src/index.ts --declaration --outDir .", - "test": "jest --coverage" + "test": "npm run -s test:code && npm run -s test:typescript", + "test:code": "jest --coverage", + "test:typescript": "npx tsc --noEmit --declaration --noUnusedLocals test-typescript.ts" }, "repository": "github:gr2m/javascript-plugin-architecture-with-typescript-definitions", "keywords": [ diff --git a/test-typescript.ts b/test-typescript.ts new file mode 100644 index 0000000..2b5cd9d --- /dev/null +++ b/test-typescript.ts @@ -0,0 +1,22 @@ +// ************************************************************ +// THIS CODE IS NOT EXECUTED. IT IS JUST FOR TYPECHECKING +// ************************************************************ + +import { Base } from "./src"; + +function isString(what: string) {} + +// sets .options types from constructor options +const base = new Base({ option: "value" }); +isString(base.options.option); + +// sets .options types from Base.defaults({}) +const BaseWithDefaults = Base.defaults({ parentOption: "value" }); +const baseWithDefaults = new BaseWithDefaults({ childOption: "value" }); + +isString(baseWithDefaults.options.childOption); +// see #32 +isString(baseWithDefaults.options.parentOption); + +// @ts-expect-error see #31 +baseWithDefaults.unknown; From a65fd91274c3ea33b7c95ad44e5db659282f2251 Mon Sep 17 00:00:00 2001 From: Gregor Martynus <39992+gr2m@users.noreply.github.com> Date: Tue, 6 Apr 2021 14:11:18 -0700 Subject: [PATCH 2/2] feat(typescript): Inherit options types set in `Base.defaults()` --- src/index.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 94448ba..22b6777 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,7 +27,7 @@ type ReturnTypeOf = T extends AnyFunction ? UnionToIntersection> : never; -export class Base { +export class Base { static plugins: TestPlugin[] = []; static plugin< S extends Constructor & { plugins: any[] }, @@ -46,21 +46,25 @@ export class Base { ); }; - return BaseWithPlugins as typeof this & { plugins: any[] } & - Constructor & ReturnTypeOf>>; + return BaseWithPlugins as typeof this & { plugins: any[] } & Constructor< + UnionToIntersection & ReturnTypeOf> + >; } - static defaults>(this: S, defaults: Options) { + static defaults< + TDefaults extends Options, + S extends Constructor> + >(this: S, defaults: TDefaults) { const BaseWitDefaults = class extends this { constructor(...args: any[]) { super(Object.assign({}, defaults, args[0] || {})); } }; - return BaseWitDefaults as typeof this; + return BaseWitDefaults as typeof BaseWitDefaults & typeof this; } - constructor(options: Options = {}) { + constructor(options: TOptions = {} as TOptions) { this.options = options; // apply plugins @@ -71,5 +75,5 @@ export class Base { }); } - options: Options; -} \ No newline at end of file + options: TOptions; +}