Skip to content

Commit 3987e10

Browse files
committed
fix: 修正未处理 nullable 的问题
1 parent c4feb78 commit 3987e10

File tree

2 files changed

+81
-42
lines changed

2 files changed

+81
-42
lines changed

src/printer/Schemata.ts

Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ function withGroup(texts: string[], separator: string, start = '(', end = ')') {
1515
return start + texts.join(separator) + end;
1616
}
1717

18+
function withNullable(type: string, nullable?: boolean) {
19+
return nullable ? `(${type}) | null` : type;
20+
}
21+
1822
export class Schemata {
1923
constructor(private named: Named) {}
2024

@@ -27,15 +31,18 @@ export class Schemata {
2731
};
2832
}
2933

30-
const { type, allOf, oneOf, anyOf, default: defaultValue, deprecated, description, format, readOnly, title } = schema;
34+
const { type, allOf, oneOf, anyOf, nullable } = schema;
3135
const comments = JsDoc.fromSchema(schema);
3236

3337
if (allOf) {
3438
return {
3539
comments,
36-
type: withGroup(
37-
allOf.map((s) => this.toString(s)),
38-
'&',
40+
type: withNullable(
41+
withGroup(
42+
allOf.map((s) => this.toString(s)),
43+
'&',
44+
),
45+
nullable,
3946
),
4047
required: false,
4148
};
@@ -44,9 +51,12 @@ export class Schemata {
4451
if (oneOf) {
4552
return {
4653
comments,
47-
type: withGroup(
48-
oneOf.map((s) => this.toString(s)),
49-
'|',
54+
type: withNullable(
55+
withGroup(
56+
oneOf.map((s) => this.toString(s)),
57+
'|',
58+
),
59+
nullable,
5060
),
5161
required: false,
5262
};
@@ -55,11 +65,14 @@ export class Schemata {
5565
if (anyOf) {
5666
return {
5767
comments,
58-
type: withGroup(
59-
anyOf.map((s) => this.toString(s)),
60-
',',
61-
'AnyOf<',
62-
'>',
68+
type: withNullable(
69+
withGroup(
70+
anyOf.map((s) => this.toString(s)),
71+
',',
72+
'AnyOf<',
73+
'>',
74+
),
75+
nullable,
6376
),
6477
required: false,
6578
};
@@ -68,21 +81,24 @@ export class Schemata {
6881
if (isArray(type)) {
6982
return {
7083
comments,
71-
type: withGroup(
72-
type.map((type) =>
73-
this.toString(
74-
type === 'null'
75-
? { type }
76-
: ({
77-
// 将枚举值传给子类型
78-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
79-
// @ts-ignore
80-
enum: schema.enum,
81-
type,
82-
} as OpenApi3.SchemaObject),
84+
type: withNullable(
85+
withGroup(
86+
type.map((type) =>
87+
this.toString(
88+
type === 'null'
89+
? { type }
90+
: ({
91+
// 将枚举值传给子类型
92+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
93+
// @ts-ignore
94+
enum: schema.enum,
95+
type,
96+
} as OpenApi3.SchemaObject),
97+
),
8398
),
99+
'|',
84100
),
85-
'|',
101+
nullable,
86102
),
87103
required: false,
88104
};
@@ -93,13 +109,15 @@ export class Schemata {
93109
const { enum: enumValues = [] } = schema;
94110
return {
95111
comments,
96-
type:
112+
type: withNullable(
97113
enumValues.length > 0
98114
? withGroup(
99115
enumValues.map((e) => (isString(e) ? JSON.stringify(e) : this.named.getRefType(e.$ref) || 'unknown')),
100116
'|',
101117
)
102118
: type,
119+
nullable,
120+
),
103121
required: schema.required || false,
104122
};
105123
}
@@ -108,13 +126,15 @@ export class Schemata {
108126
const { enum: enumValues = [] } = schema;
109127
return {
110128
comments,
111-
type:
129+
type: withNullable(
112130
enumValues.length > 0
113131
? withGroup(
114132
enumValues.map((e) => (isBoolean(e) ? String(e) : this.named.getRefType(e.$ref) || 'unknown')),
115133
'|',
116134
)
117135
: type,
136+
nullable,
137+
),
118138
required: schema.required || false,
119139
};
120140
}
@@ -124,13 +144,15 @@ export class Schemata {
124144
const { enum: enumValues = [] } = schema;
125145
return {
126146
comments,
127-
type:
147+
type: withNullable(
128148
enumValues.length > 0
129149
? withGroup(
130150
enumValues.map((e) => (isNumber(e) ? String(e) : this.named.getRefType(e.$ref) || 'unknown')),
131151
'|',
132152
)
133153
: 'number',
154+
nullable,
155+
),
134156
required: schema.required || false,
135157
};
136158
}
@@ -178,7 +200,7 @@ export class Schemata {
178200
const subTypes = subSchemas.map((s) => this.toString(s));
179201
return {
180202
comments,
181-
type: explicit ? `[${subTypes.join(',')}]` : `((${subTypes.join('|')})[])`,
203+
type: withNullable(explicit ? `[${subTypes.join(',')}]` : `((${subTypes.join('|')})[])`, schema.nullable),
182204
required: false,
183205
};
184206
}
@@ -199,28 +221,35 @@ export class Schemata {
199221

200222
return {
201223
comments,
202-
type: withGroup(
203-
entries.map(([name, subSchema]) => {
204-
const { required: subRequired, comments, type } = this.print(subSchema);
205-
const required = schema.required?.includes(name) || subRequired || false;
206-
const jsDoc = new JsDoc();
207-
jsDoc.addComments(comments);
208-
return [jsDoc.print(), `${name}${requiredTypeStringify(required)}${type};`].filter(Boolean).join('\n');
209-
}),
210-
'\n',
211-
'{\n',
212-
'\n}',
224+
type: withNullable(
225+
withGroup(
226+
entries.map(([name, subSchema]) => {
227+
const { required: subRequired, comments, type } = this.print(subSchema);
228+
const required = schema.required?.includes(name) || subRequired || false;
229+
const jsDoc = new JsDoc();
230+
jsDoc.addComments(comments);
231+
return [jsDoc.print(), `${name}${requiredTypeStringify(required)}${type};`].filter(Boolean).join('\n');
232+
}),
233+
'\n',
234+
'{\n',
235+
'\n}',
236+
),
237+
schema.nullable,
213238
),
214239
required: false,
215240
};
216241
}
217242

218-
private _printUnknown(schema: OpenApi3_Schema, type: 'object' | 'array' | 'primitive' = 'primitive') {
243+
private _printUnknown(schema: OpenApi3.SchemaBaseObject & OpenApi3_Schema, type: 'object' | 'array' | 'primitive' = 'primitive') {
219244
const comments = JsDoc.fromSchema(schema);
220245

221246
return {
222247
comments,
223-
type: type === 'object' ? 'Record<keyof unknown, unknown>' : type === 'array' ? '(unknown[])' : 'unknown',
248+
type: withNullable(
249+
//
250+
type === 'object' ? 'Record<keyof unknown, unknown>' : type === 'array' ? '(unknown[])' : 'unknown',
251+
schema.nullable,
252+
),
224253
required: false,
225254
};
226255
}

test/printer/schemas.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ test('printComponents AllOf primitive', () => {
139139
},
140140
components: {
141141
schemas: {
142+
User: {
143+
type: 'object',
144+
nullable: true,
145+
properties: {
146+
username: {
147+
type: 'string',
148+
},
149+
},
150+
required: ['username'],
151+
},
142152
Order: {
143153
allOf: [
144154
{

0 commit comments

Comments
 (0)