diff --git a/.changeset/eleven-shoes-mate.md b/.changeset/eleven-shoes-mate.md
new file mode 100644
index 000000000..bb1468886
--- /dev/null
+++ b/.changeset/eleven-shoes-mate.md
@@ -0,0 +1,5 @@
+---
+"openapi-typescript": minor
+---
+
+Add support for patternProperties
diff --git a/packages/openapi-typescript/src/transform/schema-object.ts b/packages/openapi-typescript/src/transform/schema-object.ts
index 7219664df..7897f9da2 100644
--- a/packages/openapi-typescript/src/transform/schema-object.ts
+++ b/packages/openapi-typescript/src/transform/schema-object.ts
@@ -448,6 +448,7 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
   if (
     ("properties" in schemaObject && schemaObject.properties && Object.keys(schemaObject.properties).length) ||
     ("additionalProperties" in schemaObject && schemaObject.additionalProperties) ||
+    ("patternProperties" in schemaObject && schemaObject.patternProperties) ||
     ("$defs" in schemaObject && schemaObject.$defs)
   ) {
     // properties
@@ -547,13 +548,22 @@ function transformSchemaObjectCore(schemaObject: SchemaObject, options: Transfor
       );
     }
 
-    // additionalProperties
-    if (schemaObject.additionalProperties || options.ctx.additionalProperties) {
+    // additionalProperties / patternProperties
+    if (schemaObject.additionalProperties || options.ctx.additionalProperties || schemaObject.patternProperties) {
       const hasExplicitAdditionalProperties =
         typeof schemaObject.additionalProperties === "object" && Object.keys(schemaObject.additionalProperties).length;
-      const addlType = hasExplicitAdditionalProperties
-        ? transformSchemaObject(schemaObject.additionalProperties as SchemaObject, options)
-        : UNKNOWN;
+      const hasExplicitPatternProperties =
+        typeof schemaObject.patternProperties === "object" && Object.keys(schemaObject.patternProperties).length;
+      const addlTypes = [];
+      if (hasExplicitAdditionalProperties) {
+        addlTypes.push(transformSchemaObject(schemaObject.additionalProperties as SchemaObject, options));
+      }
+      if (hasExplicitPatternProperties) {
+        for (const [_, v] of getEntries(schemaObject.patternProperties ?? {}, options.ctx)) {
+          addlTypes.push(transformSchemaObject(v, options));
+        }
+      }
+      const addlType = addlTypes.length === 0 ? UNKNOWN : tsUnion(addlTypes);
       return tsIntersection([
         ...(coreObjectType.length ? [ts.factory.createTypeLiteralNode(coreObjectType)] : []),
         ts.factory.createTypeLiteralNode([
diff --git a/packages/openapi-typescript/src/types.ts b/packages/openapi-typescript/src/types.ts
index 75d8f8c07..6cb985e71 100644
--- a/packages/openapi-typescript/src/types.ts
+++ b/packages/openapi-typescript/src/types.ts
@@ -502,6 +502,7 @@ export interface ObjectSubtype {
   type: "object" | ["object", "null"];
   properties?: { [name: string]: SchemaObject | ReferenceObject };
   additionalProperties?: boolean | Record<string, never> | SchemaObject | ReferenceObject;
+  patternProperties?: Record<string, SchemaObject | ReferenceObject>;
   required?: string[];
   allOf?: (SchemaObject | ReferenceObject)[];
   anyOf?: (SchemaObject | ReferenceObject)[];
diff --git a/packages/openapi-typescript/test/transform/schema-object/object.test.ts b/packages/openapi-typescript/test/transform/schema-object/object.test.ts
index 062f734a5..4aa275e80 100644
--- a/packages/openapi-typescript/test/transform/schema-object/object.test.ts
+++ b/packages/openapi-typescript/test/transform/schema-object/object.test.ts
@@ -99,6 +99,55 @@ describe("transformSchemaObject > object", () => {
         // options: DEFAULT_OPTIONS,
       },
     ],
+    [
+      "patternProperties > empty object",
+      {
+        given: { type: "object", patternProperties: {} },
+        want: `{
+    [key: string]: unknown;
+}`,
+      },
+    ],
+    [
+      "patternProperties > basic",
+      {
+        given: { type: "object", patternProperties: { "^a": { type: "string" } } },
+        want: `{
+    [key: string]: string;
+}`,
+      },
+    ],
+    [
+      "patternProperties > enum",
+      {
+        given: { type: "object", patternProperties: { "^a": { type: "string", enum: ["a", "b", "c"] } } },
+        want: `{
+    [key: string]: "a" | "b" | "c";
+}`,
+      },
+    ],
+    [
+      "patternProperties > multiple patterns",
+      {
+        given: { type: "object", patternProperties: { "^a": { type: "string" }, "^b": { type: "number" } } },
+        want: `{
+    [key: string]: string | number;
+}`,
+      },
+    ],
+    [
+      "patternProperties > additional and patterns",
+      {
+        given: {
+          type: "object",
+          additionalProperties: { type: "number" },
+          patternProperties: { "^a": { type: "string" } },
+        },
+        want: `{
+    [key: string]: number | string;
+}`,
+      },
+    ],
     [
       "nullable",
       {