Skip to content

Commit

Permalink
fix(types): Strict store types (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
Qsppl authored Apr 3, 2024
1 parent b78e7c4 commit 9aba4be
Show file tree
Hide file tree
Showing 12 changed files with 1,042 additions and 356 deletions.
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@
"dev": "npm run karma -- --no-single-run --browsers ChromeHeadless",
"dev:coverage": "rm -rf ./coverage && NODE_ENV=coverage npm run dev",
"lint": "eslint ./src",
"test": "npm run test:cli && npm run lint && npm run karma",
"test": "npm run test:cli && npm run lint && npm run karma && npm run test:typescript",
"test:coverage": "rm -rf ./coverage && NODE_ENV=coverage npm run karma",
"test:cli": "node ./cli/test.js",
"test:setup": "playwright install firefox webkit --with-deps",
"test:typescript": "tsc --noEmit --project ./test/types/tsconfig.json",
"release": "npm run test && standard-version -a"
},
"devDependencies": {
Expand All @@ -61,7 +62,8 @@
"log4js": "^6.2.1",
"playwright": "^1.41.2",
"prettier": "^3.1.1",
"standard-version": "^9.3.2"
"standard-version": "^9.3.2",
"typescript": "^5.4.3"
},
"standard-version": {
"scripts": {
Expand Down
23 changes: 11 additions & 12 deletions test/spec/children.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,18 +292,17 @@ describe("children:", () => {
define({
tag: "test-dynamic-wrapper",
items: undefined,
render: ({ items }) =>
html`
<test-dynamic-parent>
<test-dynamic-child name="one"></test-dynamic-child>
${items &&
items.map((name) =>
html`
<test-dynamic-child name="${name}"></test-dynamic-child>
`.key(name),
)}
</test-dynamic-parent>
`,
render: ({ items }) => html`
<test-dynamic-parent>
<test-dynamic-child name="one"></test-dynamic-child>
${items &&
items.map((name) =>
html`
<test-dynamic-child name="${name}"></test-dynamic-child>
`.key(name),
)}
</test-dynamic-parent>
`,
});
});

Expand Down
5 changes: 3 additions & 2 deletions test/spec/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -1416,8 +1416,9 @@ describe("html:", () => {

customElements.define("test-external-element", TestExternalElement);

const render = (value) =>
html` <test-external-element>${value}</test-external-element> `;
const render = (value) => html`
<test-external-element>${value}</test-external-element>
`;

it("renders external element with slotted value", (done) => {
const el = document.createElement("div");
Expand Down
122 changes: 122 additions & 0 deletions test/types/store/descriptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { Model, define, store } from "/types/index";

interface IEnumerableModel {
id: string;
prop: number;
}
interface ISingletonModel {
prop: number;
}

const EnumerableDefinition: Model<IEnumerableModel> = { id: true, prop: 0 };
const SingletonDefinition: Model<ISingletonModel> = { prop: 0 };

interface IAComponent extends HTMLElement {
modelId: undefined | string;

singleton: ISingletonModel;
singletonDraft: ISingletonModel;
model: undefined | IEnumerableModel;
modelDraft: IEnumerableModel;

singletonById: ISingletonModel;
singletonDraftById: ISingletonModel;
modelById: undefined | IEnumerableModel;
modelDraftById: IEnumerableModel;

singletonList: ISingletonModel[];
singletonDraftList: ISingletonModel[];
modelList: IEnumerableModel[];
modelDraftList: IEnumerableModel[];

singletonListById: ISingletonModel[];
singletonDraftListById: ISingletonModel[];
modelListById: IEnumerableModel[];
modelDraftListById: IEnumerableModel[];

looseSingletonList: ISingletonModel[];
looseSingletonDraftList: ISingletonModel[];
looseModelList: IEnumerableModel[];
looseModelDraftList: IEnumerableModel[];

looseSingletonListById: ISingletonModel[];
looseSingletonDraftListById: ISingletonModel[];
looseModelListById: IEnumerableModel[];
looseModelDraftListById: IEnumerableModel[];
}

const Component = define<IAComponent>({
tag: "a-component",
modelId: undefined,

singleton: store(SingletonDefinition),
singletonDraft: store(SingletonDefinition, { draft: true }),
model: store(EnumerableDefinition),
modelDraft: store(EnumerableDefinition, { draft: true }),

singletonById: store(SingletonDefinition, { id: "modelId" }),
singletonDraftById: store(SingletonDefinition, {
id: "modelId",
draft: true,
}),
modelById: store(EnumerableDefinition, { id: "modelId" }),
modelDraftById: store(EnumerableDefinition, { draft: true, id: "modelId" }),

/// @ts-expect-error
singletonList: store([SingletonDefinition]),
/// @ts-expect-error
singletonDraftList: store([SingletonDefinition], { draft: true }),
modelList: store([EnumerableDefinition]),
/// @ts-expect-error
modelDraftList: store([EnumerableDefinition], { draft: true }),

/// @ts-expect-error
singletonListById: store([SingletonDefinition], { id: "modelId" }),
/// @ts-expect-error
singletonDraftListById: store([SingletonDefinition], {
id: "modelId",
draft: true,
}),
modelListById: store([EnumerableDefinition], { id: "modelId" }),
/// @ts-expect-error
modelDraftListById: store([EnumerableDefinition], {
id: "modelId",
draft: true,
}),

/// @ts-expect-error
looseSingletonList: store([SingletonDefinition], { loose: true }),
/// @ts-expect-error
looseSingletonDraftList: store([SingletonDefinition], {
draft: true,
loose: true,
}),
looseModelList: store([EnumerableDefinition], { loose: true }),
/// @ts-expect-error
looseModelDraftList: store([EnumerableDefinition], {
draft: true,
loose: true,
}),

/// @ts-expect-error
looseSingletonListById: store([SingletonDefinition], {
id: "modelId",
loose: true,
}),
/// @ts-expect-error
looseSingletonDraftListById: store([SingletonDefinition], {
id: "modelId",
draft: true,
loose: true,
}),
looseModelListById: store([EnumerableDefinition], {
id: "modelId",
loose: true,
}),
/// @ts-expect-error
looseModelDraftListById: store([EnumerableDefinition], {
id: "modelId",
draft: true,
loose: true,
}),
});
6 changes: 6 additions & 0 deletions test/types/store/direct-methods.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { store } from "/types/index";
import SingletonStore, { ISingleton } from "./singleton-definition.store";
import EnumerableStore, { IEnumerable } from "./enumerable-definition.store";

const SingletonNodel: Promise<ISingleton> = store.resolve(SingletonStore);
const EnumerableNodel: Promise<IEnumerable> = store.resolve(EnumerableStore);
27 changes: 27 additions & 0 deletions test/types/store/enumerable-definition.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Model, store } from "/types/index";

export interface IEnumerable {
id: string;
prop: string;
length: number;
relatedModel?: IEnumerable;
relatedModels: IEnumerable[];
}

const EnumerableStore: Model<IEnumerable> = {
id: true,
prop: "",
length: 0,
relatedModel: store.ref(() => EnumerableStore),
relatedModels: store.ref(() => [EnumerableStore]),
};

export default EnumerableStore;

/// @ts-expect-error
const BrokenEnumerableStore: Model<IEnumerable> = {
prop: "",
length: 0,
relatedModel: store.ref(() => EnumerableStore),
relatedModels: store.ref(() => [EnumerableStore]),
};
Loading

0 comments on commit 9aba4be

Please sign in to comment.