Skip to content

Commit ea41f7b

Browse files
committed
wip
1 parent d780bff commit ea41f7b

File tree

7 files changed

+108
-25
lines changed

7 files changed

+108
-25
lines changed

examples/required-options/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# required options Example
2+
3+
`Base` has no required options by default, so the following code has no type errors.
4+
5+
```js
6+
import { Base } from "javascript-plugin-architecture-with-typescript-definitions";
7+
8+
const base1 = new Base();
9+
const base2 = new Base({});
10+
```
11+
12+
But required options can be added by extending the `Base.Optiions` interface.
13+
14+
```ts
15+
declare module "javascript-plugin-architecture-with-typescript-definitions" {
16+
namespace Base {
17+
interface Options {
18+
myRequiredUserOption: string;
19+
}
20+
}
21+
}
22+
```
23+
24+
With that extension, the same code will have type a type error
25+
26+
```ts
27+
// TS Error: Property 'myRequiredUserOption' is missing in type '{}' but required in type 'Options'
28+
const base = new Base({});
29+
```

examples/required-options/index.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Base } from "../../index.js";
2+
export { Base } from "../../index.js";
3+
4+
declare module "../.." {
5+
namespace Base {
6+
interface Options {
7+
myRequiredUserOption: string;
8+
}
9+
}
10+
}
11+
12+
export class MyBase extends Base {}

examples/required-options/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Base } from "../../index.js";
2+
3+
/**
4+
* @param {Base} base
5+
* @param {Base.Options} options
6+
*/
7+
function pluginRequiringOption(base, options) {
8+
if (!options.myRequiredUserOption) {
9+
throw new Error('Required option "myRequiredUserOption" missing');
10+
}
11+
}
12+
13+
export const MyBase = Base.plugin(pluginRequiringOption);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { MyBase } from "./index.js";
2+
3+
// @ts-expect-error - An argument for 'options' was not provided
4+
new MyBase();
5+
6+
// @ts-expect-error - Type '{}' is missing the following properties from type 'Options': myRequiredUserOption
7+
new MyBase({});
8+
9+
new MyBase({
10+
myRequiredUserOption: "",
11+
});

examples/required-options/test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { test } from "uvu";
2+
import * as assert from "uvu/assert";
3+
4+
import { MyBase } from "./index.js";
5+
6+
test("new MyBase()", () => {
7+
assert.throws(() => new MyBase());
8+
});
9+
10+
test("new MyBase({})", () => {
11+
assert.throws(() => new MyBase({}));
12+
});
13+
14+
test('new MyBase({ myRequiredUserOption: ""})', () => {
15+
assert.not.throws(() => new MyBase({ myRequiredUserOption: "" }));
16+
});
17+
18+
test.run();

index.test-d.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ const BaseWithEmptyDefaults = Base.defaults({
1919

2020
// 'version' is missing and should still be required
2121
// @ts-expect-error
22-
new BaseWithEmptyDefaults()
22+
new BaseWithEmptyDefaults();
2323

2424
// 'version' is missing and should still be required
2525
// @ts-expect-error
26-
new BaseWithEmptyDefaults({})
26+
new BaseWithEmptyDefaults({});
2727

2828
const BaseLevelOne = Base.plugin(fooPlugin).defaults({
2929
defaultOne: "value",
@@ -35,8 +35,8 @@ new BaseLevelOne();
3535
new BaseLevelOne({});
3636

3737
expectType<{
38-
defaultOne: string,
39-
version: string,
38+
defaultOne: string;
39+
version: string;
4040
}>(BaseLevelOne.defaultOptions);
4141

4242
const baseLevelOne = new BaseLevelOne({
@@ -54,9 +54,9 @@ const BaseLevelTwo = BaseLevelOne.defaults({
5454
});
5555

5656
expectType<{
57-
defaultOne: string,
58-
defaultTwo: number,
59-
version: string,
57+
defaultOne: string;
58+
defaultTwo: number;
59+
version: string;
6060
}>({ ...BaseLevelTwo.defaultOptions });
6161

6262
// Because 'version' is already provided, this needs no argument
@@ -65,11 +65,11 @@ new BaseLevelTwo({});
6565

6666
// 'version' may be overriden, though it's not necessary
6767
new BaseLevelTwo({
68-
version: 'new version',
68+
version: "new version",
6969
});
7070

7171
const baseLevelTwo = new BaseLevelTwo({
72-
optionTwo: true
72+
optionTwo: true,
7373
});
7474

7575
expectType<number>(baseLevelTwo.options.defaultTwo);
@@ -80,14 +80,14 @@ expectType<string>(baseLevelTwo.options.version);
8080
baseLevelTwo.unknown;
8181

8282
const BaseLevelThree = BaseLevelTwo.defaults({
83-
defaultThree: ['a', 'b', 'c'],
83+
defaultThree: ["a", "b", "c"],
8484
});
8585

8686
expectType<{
87-
defaultOne: string,
88-
defaultTwo: number,
89-
defaultThree: string[],
90-
version: string,
87+
defaultOne: string;
88+
defaultTwo: number;
89+
defaultThree: string[];
90+
version: string;
9191
}>({ ...BaseLevelThree.defaultOptions });
9292

9393
// Because 'version' is already provided, this needs no argument
@@ -96,13 +96,13 @@ new BaseLevelThree({});
9696

9797
// Previous settings may be overriden, though it's not necessary
9898
new BaseLevelThree({
99-
optionOne: '',
99+
optionOne: "",
100100
optionTwo: false,
101-
version: 'new version',
101+
version: "new version",
102102
});
103103

104104
const baseLevelThree = new BaseLevelThree({
105-
optionThree: [0, 1, 2]
105+
optionThree: [0, 1, 2],
106106
});
107107

108108
expectType<string>(baseLevelThree.options.defaultOne);
@@ -185,19 +185,19 @@ expectType<{
185185
// @ts-expect-error - .options from .defaults() is only supported until a depth of 4
186186
}>({ ...baseLevelFour.options });
187187

188-
const BaseWithChainedDefaultsAndPlugins = Base
189-
.defaults({
190-
defaultOne: "value",
191-
})
188+
const BaseWithChainedDefaultsAndPlugins = Base.defaults({
189+
defaultOne: "value",
190+
})
192191
.plugin(fooPlugin)
193192
.defaults({
194193
defaultTwo: 0,
195194
});
196195

197-
const baseWithChainedDefaultsAndPlugins =
198-
new BaseWithChainedDefaultsAndPlugins({
196+
const baseWithChainedDefaultsAndPlugins = new BaseWithChainedDefaultsAndPlugins(
197+
{
199198
version: "1.2.3",
200-
});
199+
}
200+
);
201201

202202
expectType<string>(baseWithChainedDefaultsAndPlugins.foo);
203203

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"test": "npm run -s test:code && npm run -s test:typescript && npm run -s test:coverage",
1515
"test:code": "c8 node test.js",
1616
"test:coverage": "c8 check-coverage",
17-
"test:typescript": "tsd"
17+
"test:typescript": "tsd && tsd examples/*"
1818
},
1919
"repository": "github:gr2m/javascript-plugin-architecture-with-typescript-definitions",
2020
"keywords": [

0 commit comments

Comments
 (0)