Skip to content

Commit c1b9dcb

Browse files
committed
fix(#31): anyOf to ts
1 parent 93bd157 commit c1b9dcb

File tree

5 files changed

+24
-23
lines changed

5 files changed

+24
-23
lines changed

.changeset/ten-beers-travel.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"typed-openapi": minor
3+
---
4+
5+
fix: anyOf to ts
6+
7+
https://github.com/astahmer/typed-openapi/issues/31

packages/typed-openapi/src/openapi-schema-to-ts.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ export const openApiSchemaToTs = ({ schema, meta: _inheritedMeta, ctx }: Openapi
4040
return t.union(schema.oneOf.map((prop) => openApiSchemaToTs({ schema: prop, ctx, meta })));
4141
}
4242

43-
// anyOf = oneOf but with 1 or more = `T extends oneOf ? T | T[] : never`
43+
// tl;dr: anyOf = oneOf
44+
// oneOf matches exactly one subschema, and anyOf can match one or more subschemas.
45+
// https://swagger.io/docs/specification/v3_0/data-models/oneof-anyof-allof-not/
4446
if (schema.anyOf) {
4547
if (schema.anyOf.length === 1) {
4648
return openApiSchemaToTs({ schema: schema.anyOf[0]!, ctx, meta });
4749
}
4850

49-
const oneOf = t.union(schema.anyOf.map((prop) => openApiSchemaToTs({ schema: prop, ctx, meta })));
50-
return t.union([oneOf, t.array(oneOf)]);
51+
return t.union(schema.anyOf.map((prop) => openApiSchemaToTs({ schema: prop, ctx, meta })));
5152
}
5253

5354
if (schema.allOf) {

packages/typed-openapi/tests/generator-basic-schemas.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,11 @@ test("getSchemaBox", async () => {
154154
expect(await getSchemaBox({ allOf: [{ type: "string" }, { type: "number" }] })).toMatchInlineSnapshot(`"export type _Test = string & number;"`);
155155

156156
expect(await getSchemaBox({ anyOf: [{ type: "string" }, { type: "number" }] })).toMatchInlineSnapshot(
157-
`"export type _Test = string | number | Array<string | number>;"`,
157+
`"export type _Test = string | number;"`,
158158
);
159159

160160
// StringAndNumberMaybeMultiple
161-
expect(await getSchemaBox({ anyOf: [{ type: "string" }, { type: "number" }] })).toMatchInlineSnapshot(`"export type _Test = string | number | Array<string | number>;"`);
161+
expect(await getSchemaBox({ anyOf: [{ type: "string" }, { type: "number" }] })).toMatchInlineSnapshot(`"export type _Test = string | number;"`);
162162

163163
// ObjectWithArrayUnion
164164
expect(
@@ -168,7 +168,7 @@ test("getSchemaBox", async () => {
168168
unionOrArrayOfUnion: { anyOf: [{ type: "string" }, { type: "number" }] },
169169
},
170170
}),
171-
).toMatchInlineSnapshot(`"export type _Test = Partial<{ unionOrArrayOfUnion: string | number | Array<string | number> }>;"`);
171+
).toMatchInlineSnapshot(`"export type _Test = Partial<{ unionOrArrayOfUnion: string | number }>;"`);
172172

173173
// ObjectWithIntersection
174174
expect(
@@ -393,7 +393,7 @@ describe("getSchemaBox with context", () => {
393393
`
394394
{
395395
"type": "ref",
396-
"value": "Partial<{ user: User | Member, users: Array<User | Member | Array<User | Member>>, basic: number }>",
396+
"value": "Partial<{ user: User | Member, users: Array<User | Member>, basic: number }>",
397397
}
398398
`,
399399
);

packages/typed-openapi/tests/generator.test.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -691,14 +691,7 @@ describe("generator", () => {
691691
parameters: {
692692
query: Partial<{
693693
searchQuery: string;
694-
includeRoles: Array<
695-
| "super-admin"
696-
| "buyer"
697-
| "admin"
698-
| "coordinator"
699-
| "requestor"
700-
| Array<"super-admin" | "buyer" | "admin" | "coordinator" | "requestor">
701-
>;
694+
includeRoles: Array<"super-admin" | "buyer" | "admin" | "coordinator" | "requestor">;
702695
}>;
703696
path: { organizationId: string };
704697
};

packages/typed-openapi/tests/openapi-schema-to-ts.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -300,18 +300,18 @@ test("getSchemaBox", () => {
300300
`
301301
{
302302
"type": "union",
303-
"value": "string | number | Array<string | number>",
303+
"value": "string | number",
304304
}
305305
`,
306306
);
307307

308308
// StringAndNumberMaybeMultiple
309309
expect(getSchemaBox({ anyOf: [{ type: "string" }, { type: "number" }] })).toMatchInlineSnapshot(`
310-
{
311-
"type": "union",
312-
"value": "string | number | Array<string | number>",
313-
}
314-
`);
310+
{
311+
"type": "union",
312+
"value": "string | number",
313+
}
314+
`);
315315

316316
// ObjectWithArrayUnion
317317
expect(
@@ -324,7 +324,7 @@ test("getSchemaBox", () => {
324324
).toMatchInlineSnapshot(`
325325
{
326326
"type": "ref",
327-
"value": "Partial<{ unionOrArrayOfUnion: string | number | Array<string | number> }>",
327+
"value": "Partial<{ unionOrArrayOfUnion: string | number }>",
328328
}
329329
`);
330330

@@ -610,7 +610,7 @@ describe("getSchemaBox with context", () => {
610610
`
611611
{
612612
"type": "ref",
613-
"value": "Partial<{ user: User | Member, users: Array<User | Member | Array<User | Member>>, basic: number }>",
613+
"value": "Partial<{ user: User | Member, users: Array<User | Member>, basic: number }>",
614614
}
615615
`,
616616
);

0 commit comments

Comments
 (0)