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);
+    },
+  );
 });