Skip to content

Commit c729f3d

Browse files
committed
feat: add Refiner type
1 parent 39fc25a commit c729f3d

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from "./curator.ts";
44
export * from "./item.ts";
55
export * from "./matcher.ts";
66
export * from "./previewer.ts";
7+
export * from "./refiner.ts";
78
export * from "./renderer.ts";
89
export * from "./sorter.ts";
910
export * from "./source.ts";

refiner.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { Denops } from "@denops/std";
2+
import type { Detail, DetailUnit, IdItem } from "./item.ts";
3+
4+
/**
5+
* Parameters for refining a source or curator.
6+
*/
7+
export type RefineParams<T extends Detail> = {
8+
readonly items: AsyncIterable<IdItem<T>>;
9+
};
10+
11+
/**
12+
* Refiner that refine a source or curator.
13+
*/
14+
export type Refiner<
15+
T extends Detail = DetailUnit,
16+
U extends Detail = DetailUnit,
17+
> = {
18+
__phantom?: (_: T) => void; // This is required for type constraint.
19+
20+
/**
21+
* Refine a source or curator.
22+
*
23+
* @param denops Denops instance.
24+
* @param params Parameters for refining.
25+
* @param options - Additional options, including an abort signal.
26+
* @returns An async iterator over the collected or curated items.
27+
*/
28+
refine: <V extends T>(
29+
denops: Denops,
30+
params: RefineParams<V>,
31+
options: { signal?: AbortSignal },
32+
) => AsyncIterableIterator<IdItem<V & U>>;
33+
};

refiner_test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { assertType, type IsExact } from "@std/testing/types";
2+
import { DenopsStub } from "@denops/test/stub";
3+
import type { DetailUnit } from "./item.ts";
4+
import type { RefineParams, Refiner } from "./refiner.ts";
5+
6+
Deno.test("Refiner", async (t) => {
7+
const denops = new DenopsStub();
8+
9+
await t.step("without type constraint is equal to UnitDetail", () => {
10+
assertType<IsExact<Refiner, Refiner<DetailUnit>>>(true);
11+
});
12+
13+
await t.step("preview follows the type constraint", () => {
14+
const previewer: Refiner<{ a: string }> = { refine: async function* () {} };
15+
previewer.refine(denops, {} as RefineParams<{ a: string }>, {});
16+
previewer.refine(
17+
denops,
18+
{} as RefineParams<{ a: string; b: string }>,
19+
{},
20+
);
21+
// @ts-expect-error: 'a' is missing
22+
previewer.refine(denops, {} as RefineParams<{ b: string }>, {});
23+
// @ts-expect-error: 'a' is missing
24+
previewer.refine(denops, {} as RefineParams<Detail>, {});
25+
// @ts-expect-error: 'a' is missing
26+
previewer.refine(denops, {} as RefineParams<DetailUnit>, {});
27+
});
28+
});

0 commit comments

Comments
 (0)