diff --git a/action_test.ts b/action_test.ts index ec234d7..3aa1541 100644 --- a/action_test.ts +++ b/action_test.ts @@ -8,6 +8,7 @@ Deno.test("Action", async (t) => { const action: Action<{ a: string }> = { invoke: () => {}, }; + await t.step("passed type is equal to the type restriction", () => { const items = action.invoke( denops, @@ -50,4 +51,25 @@ Deno.test("Action", async (t) => { > >(true); }); + + await t.step( + "check if the type constraint correctly triggers the type checking", + () => { + const action1: Action<{ a: string }> = { + invoke: () => {}, + }; + const action2: Action<{ b: string }> = { + invoke: () => {}, + }; + const action3: Action<{ c: string }> = { + invoke: () => {}, + }; + function strictFunction<T extends { a: string }>(_: Action<T>) {} + strictFunction(action1); + // @ts-expect-error: 'a' is missing + strictFunction(action2); + // @ts-expect-error: 'a' is missing + strictFunction(action3); + }, + ); }); diff --git a/matcher.ts b/matcher.ts index 5839a08..4834ff0 100644 --- a/matcher.ts +++ b/matcher.ts @@ -19,6 +19,8 @@ export type MatchParams<T> = { * Matcher that filters items based on user input. */ export type Matcher<T> = { + __phantom?: T; // This is required for type constraint. + /** * Matches items against the provided query. * diff --git a/matcher_test.ts b/matcher_test.ts index adfcd27..3bf6ff5 100644 --- a/matcher_test.ts +++ b/matcher_test.ts @@ -51,4 +51,25 @@ Deno.test("Matcher", async (t) => { > >(true); }); + + await t.step( + "check if the type constraint correctly triggers the type checking", + () => { + const matcher1: Matcher<{ a: string }> = { + match: async function* () {}, + }; + const matcher2: Matcher<{ b: string }> = { + match: async function* () {}, + }; + const matcher3: Matcher<{ c: string }> = { + match: async function* () {}, + }; + function strictFunction<T extends { a: string }>(_: Matcher<T>) {} + strictFunction(matcher1); + // @ts-expect-error: 'a' is missing + strictFunction(matcher2); + // @ts-expect-error: 'a' is missing + strictFunction(matcher3); + }, + ); }); diff --git a/previewer_test.ts b/previewer_test.ts index 6bdc06c..53c3186 100644 --- a/previewer_test.ts +++ b/previewer_test.ts @@ -52,4 +52,25 @@ Deno.test("Previewer", async (t) => { > >(true); }); + + await t.step( + "check if the type constraint correctly triggers the type checking", + () => { + const previewer1: Previewer<{ a: string }> = { + preview: () => {}, + }; + const previewer2: Previewer<{ b: string }> = { + preview: () => {}, + }; + const previewer3: Previewer<{ c: string }> = { + preview: () => {}, + }; + function strictFunction<T extends { a: string }>(_: Previewer<T>) {} + strictFunction(previewer1); + // @ts-expect-error: 'a' is missing + strictFunction(previewer2); + // @ts-expect-error: 'a' is missing + strictFunction(previewer3); + }, + ); }); diff --git a/renderer_test.ts b/renderer_test.ts index f96e629..05c2c70 100644 --- a/renderer_test.ts +++ b/renderer_test.ts @@ -51,4 +51,25 @@ Deno.test("Renderer", async (t) => { > >(true); }); + + await t.step( + "check if the type constraint correctly triggers the type checking", + () => { + const renderer1: Renderer<{ a: string }> = { + render: () => {}, + }; + const renderer2: Renderer<{ b: string }> = { + render: () => {}, + }; + const renderer3: Renderer<{ c: string }> = { + render: () => {}, + }; + function strictFunction<T extends { a: string }>(_: Renderer<T>) {} + strictFunction(renderer1); + // @ts-expect-error: 'a' is missing + strictFunction(renderer2); + // @ts-expect-error: 'a' is missing + strictFunction(renderer3); + }, + ); }); diff --git a/sorter_test.ts b/sorter_test.ts index d5bd70a..d03a459 100644 --- a/sorter_test.ts +++ b/sorter_test.ts @@ -51,4 +51,25 @@ Deno.test("Sorter", async (t) => { > >(true); }); + + await t.step( + "check if the type constraint correctly triggers the type checking", + () => { + const sorter1: Sorter<{ a: string }> = { + sort: () => {}, + }; + const sorter2: Sorter<{ b: string }> = { + sort: () => {}, + }; + const sorter3: Sorter<{ c: string }> = { + sort: () => {}, + }; + function strictFunction<T extends { a: string }>(_: Sorter<T>) {} + strictFunction(sorter1); + // @ts-expect-error: 'a' is missing + strictFunction(sorter2); + // @ts-expect-error: 'a' is missing + strictFunction(sorter3); + }, + ); });