@type-crafter/mcp 0.6.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -221
- package/dist/docs/RULES_COMPOSITION.md +343 -0
- package/dist/docs/RULES_NULLABLE.md +293 -0
- package/dist/docs/RULES_PATTERNS.md +516 -0
- package/dist/docs/RULES_REFERENCES.md +302 -0
- package/dist/docs/RULES_STRUCTURE.md +248 -0
- package/dist/docs/RULES_TYPES.md +291 -0
- package/dist/docs/WRITING_GUIDE.md +179 -0
- package/dist/index.js +321 -345
- package/package.json +3 -5
- package/src/GUIDE.md +0 -459
- package/src/SPEC_RULES.md +0 -1755
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# Composition Rules
|
|
2
|
+
|
|
3
|
+
## oneOf - Union Types
|
|
4
|
+
|
|
5
|
+
Creates TypeScript union: `TypeA | TypeB | TypeC`
|
|
6
|
+
|
|
7
|
+
Use when a value can be ONE of several types.
|
|
8
|
+
|
|
9
|
+
### Basic Union
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
Response:
|
|
13
|
+
oneOf:
|
|
14
|
+
- $ref: '#/types/SuccessResponse'
|
|
15
|
+
- $ref: '#/types/ErrorResponse'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**TypeScript:** `export type Response = SuccessResponse | ErrorResponse;`
|
|
19
|
+
|
|
20
|
+
### Union with Primitives
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
Value:
|
|
24
|
+
oneOf:
|
|
25
|
+
- type: string
|
|
26
|
+
- type: number
|
|
27
|
+
- type: boolean
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**TypeScript:** `export type Value = string | number | boolean;`
|
|
31
|
+
|
|
32
|
+
### Union with Inline Objects
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
Result:
|
|
36
|
+
oneOf:
|
|
37
|
+
- type: object
|
|
38
|
+
required: [data]
|
|
39
|
+
properties:
|
|
40
|
+
data: { type: string }
|
|
41
|
+
- type: object
|
|
42
|
+
required: [error]
|
|
43
|
+
properties:
|
|
44
|
+
error: { type: string }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**TypeScript:**
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
export type Result = { data: string } | { error: string };
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Union with Arrays
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
Items:
|
|
57
|
+
oneOf:
|
|
58
|
+
- type: string
|
|
59
|
+
- type: array
|
|
60
|
+
items:
|
|
61
|
+
type: string
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**TypeScript:** `export type Items = string | string[];`
|
|
65
|
+
|
|
66
|
+
### Union with Enums
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
Status:
|
|
70
|
+
oneOf:
|
|
71
|
+
- type: string
|
|
72
|
+
enum: [pending, loading]
|
|
73
|
+
- type: string
|
|
74
|
+
enum: [success, error]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**TypeScript:** `export type Status = 'pending' | 'loading' | 'success' | 'error';`
|
|
78
|
+
|
|
79
|
+
### Complex Union Example
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
ApiResponse:
|
|
83
|
+
oneOf:
|
|
84
|
+
- $ref: '#/types/User'
|
|
85
|
+
- $ref: '#/types/Error'
|
|
86
|
+
- type: string
|
|
87
|
+
- type: number
|
|
88
|
+
- type: string
|
|
89
|
+
enum: [pending, loading]
|
|
90
|
+
- type: object
|
|
91
|
+
properties:
|
|
92
|
+
status: { type: string }
|
|
93
|
+
- type: array
|
|
94
|
+
items:
|
|
95
|
+
type: string
|
|
96
|
+
- type: array
|
|
97
|
+
items:
|
|
98
|
+
$ref: '#/types/User'
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**TypeScript:**
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
export type ApiResponse =
|
|
105
|
+
| User
|
|
106
|
+
| Error
|
|
107
|
+
| string
|
|
108
|
+
| number
|
|
109
|
+
| ('pending' | 'loading')
|
|
110
|
+
| { status: string | null }
|
|
111
|
+
| string[]
|
|
112
|
+
| User[];
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## allOf - Intersection/Merge Types
|
|
118
|
+
|
|
119
|
+
Creates TypeScript intersection: `TypeA & TypeB & TypeC`
|
|
120
|
+
|
|
121
|
+
Use to combine multiple types into one (all properties merged).
|
|
122
|
+
|
|
123
|
+
### Basic Intersection
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
AdminUser:
|
|
127
|
+
allOf:
|
|
128
|
+
- $ref: '#/types/BaseUser'
|
|
129
|
+
- $ref: '#/types/AdminPermissions'
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**TypeScript:** `export type AdminUser = BaseUser & AdminPermissions;`
|
|
133
|
+
|
|
134
|
+
### Intersection with Inline Extension
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
types:
|
|
138
|
+
BaseUser:
|
|
139
|
+
type: object
|
|
140
|
+
required: [id]
|
|
141
|
+
properties:
|
|
142
|
+
id: { type: string }
|
|
143
|
+
|
|
144
|
+
ExtendedUser:
|
|
145
|
+
allOf:
|
|
146
|
+
- $ref: '#/types/BaseUser'
|
|
147
|
+
- type: object
|
|
148
|
+
required: [email]
|
|
149
|
+
properties:
|
|
150
|
+
email: { type: string }
|
|
151
|
+
name: { type: string }
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**TypeScript:**
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
export type BaseUser = {
|
|
158
|
+
id: string;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export type ExtendedUser = BaseUser & {
|
|
162
|
+
email: string;
|
|
163
|
+
name: string | null;
|
|
164
|
+
};
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Multiple Inheritance Pattern
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
types:
|
|
171
|
+
Timestamped:
|
|
172
|
+
type: object
|
|
173
|
+
required: [createdAt, updatedAt]
|
|
174
|
+
properties:
|
|
175
|
+
createdAt: { type: string, format: date }
|
|
176
|
+
updatedAt: { type: string, format: date }
|
|
177
|
+
|
|
178
|
+
Identifiable:
|
|
179
|
+
type: object
|
|
180
|
+
required: [id]
|
|
181
|
+
properties:
|
|
182
|
+
id: { type: string }
|
|
183
|
+
|
|
184
|
+
User:
|
|
185
|
+
allOf:
|
|
186
|
+
- $ref: '#/types/Timestamped'
|
|
187
|
+
- $ref: '#/types/Identifiable'
|
|
188
|
+
- type: object
|
|
189
|
+
required: [email]
|
|
190
|
+
properties:
|
|
191
|
+
email: { type: string }
|
|
192
|
+
name: { type: string }
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**TypeScript:**
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
export type User = Timestamped &
|
|
199
|
+
Identifiable & {
|
|
200
|
+
email: string;
|
|
201
|
+
name: string | null;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// Effectively:
|
|
205
|
+
// {
|
|
206
|
+
// createdAt: Date;
|
|
207
|
+
// updatedAt: Date;
|
|
208
|
+
// id: string;
|
|
209
|
+
// email: string;
|
|
210
|
+
// name: string | null;
|
|
211
|
+
// }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Combining oneOf and allOf
|
|
217
|
+
|
|
218
|
+
You can nest composition operators:
|
|
219
|
+
|
|
220
|
+
### Union of Intersections
|
|
221
|
+
|
|
222
|
+
```yaml
|
|
223
|
+
Response:
|
|
224
|
+
oneOf:
|
|
225
|
+
- allOf:
|
|
226
|
+
- $ref: '#/types/BaseResponse'
|
|
227
|
+
- type: object
|
|
228
|
+
properties:
|
|
229
|
+
data: { $ref: '#/types/User' }
|
|
230
|
+
- allOf:
|
|
231
|
+
- $ref: '#/types/BaseResponse'
|
|
232
|
+
- type: object
|
|
233
|
+
properties:
|
|
234
|
+
error: { type: string }
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Intersection with Union Property
|
|
238
|
+
|
|
239
|
+
```yaml
|
|
240
|
+
Entity:
|
|
241
|
+
allOf:
|
|
242
|
+
- $ref: '#/types/BaseEntity'
|
|
243
|
+
- type: object
|
|
244
|
+
properties:
|
|
245
|
+
status:
|
|
246
|
+
oneOf:
|
|
247
|
+
- type: string
|
|
248
|
+
enum: [active, inactive]
|
|
249
|
+
- type: number
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Common Patterns
|
|
255
|
+
|
|
256
|
+
### Discriminated Union (Tagged Union)
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
types:
|
|
260
|
+
SuccessResult:
|
|
261
|
+
type: object
|
|
262
|
+
required: [type, data]
|
|
263
|
+
properties:
|
|
264
|
+
type:
|
|
265
|
+
type: string
|
|
266
|
+
enum: [success]
|
|
267
|
+
data: { type: unknown }
|
|
268
|
+
|
|
269
|
+
ErrorResult:
|
|
270
|
+
type: object
|
|
271
|
+
required: [type, message]
|
|
272
|
+
properties:
|
|
273
|
+
type:
|
|
274
|
+
type: string
|
|
275
|
+
enum: [error]
|
|
276
|
+
message: { type: string }
|
|
277
|
+
|
|
278
|
+
Result:
|
|
279
|
+
oneOf:
|
|
280
|
+
- $ref: '#/types/SuccessResult'
|
|
281
|
+
- $ref: '#/types/ErrorResult'
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**TypeScript:**
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
export type Result = { type: 'success'; data: unknown } | { type: 'error'; message: string };
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Mixin Pattern
|
|
291
|
+
|
|
292
|
+
```yaml
|
|
293
|
+
types:
|
|
294
|
+
WithTimestamps:
|
|
295
|
+
type: object
|
|
296
|
+
required: [createdAt]
|
|
297
|
+
properties:
|
|
298
|
+
createdAt: { type: string, format: date }
|
|
299
|
+
updatedAt: { type: string, format: date }
|
|
300
|
+
|
|
301
|
+
WithSoftDelete:
|
|
302
|
+
type: object
|
|
303
|
+
properties:
|
|
304
|
+
deletedAt: { type: string, format: date }
|
|
305
|
+
|
|
306
|
+
User:
|
|
307
|
+
allOf:
|
|
308
|
+
- $ref: '#/types/WithTimestamps'
|
|
309
|
+
- $ref: '#/types/WithSoftDelete'
|
|
310
|
+
- type: object
|
|
311
|
+
required: [id, email]
|
|
312
|
+
properties:
|
|
313
|
+
id: { type: string }
|
|
314
|
+
email: { type: string }
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Nullable Union
|
|
318
|
+
|
|
319
|
+
```yaml
|
|
320
|
+
MaybeUser:
|
|
321
|
+
oneOf:
|
|
322
|
+
- $ref: '#/types/User'
|
|
323
|
+
- type: object
|
|
324
|
+
properties: {} # Empty object as "null" representation
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Rules Summary
|
|
330
|
+
|
|
331
|
+
| Operator | TypeScript | Use Case |
|
|
332
|
+
| -------- | ------------- | ----------------------------- |
|
|
333
|
+
| `oneOf` | `A \| B \| C` | Value is one of several types |
|
|
334
|
+
| `allOf` | `A & B & C` | Combine/merge multiple types |
|
|
335
|
+
|
|
336
|
+
### What Can Be in oneOf/allOf
|
|
337
|
+
|
|
338
|
+
- `$ref` to other types
|
|
339
|
+
- `type: object` with properties
|
|
340
|
+
- `type: string/number/boolean` primitives
|
|
341
|
+
- `type: string` with `enum`
|
|
342
|
+
- `type: array` with items
|
|
343
|
+
- Nested `oneOf` or `allOf`
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Nullable Types Rules
|
|
2
|
+
|
|
3
|
+
## The Core Rule
|
|
4
|
+
|
|
5
|
+
**Properties NOT in the `required` array become `Type | null` in TypeScript.**
|
|
6
|
+
|
|
7
|
+
This is the ONLY way to control nullability. No other mechanism exists.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What Does NOT Work
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
# WRONG: nullable property does NOT exist
|
|
15
|
+
name:
|
|
16
|
+
type: string
|
|
17
|
+
nullable: true # INVALID - will be ignored or error
|
|
18
|
+
|
|
19
|
+
# WRONG: optional property does NOT exist
|
|
20
|
+
name:
|
|
21
|
+
type: string
|
|
22
|
+
optional: true # INVALID - will be ignored or error
|
|
23
|
+
|
|
24
|
+
# WRONG: ? suffix is NOT supported
|
|
25
|
+
properties:
|
|
26
|
+
name?: # INVALID SYNTAX
|
|
27
|
+
type: string
|
|
28
|
+
|
|
29
|
+
# WRONG: Array type syntax
|
|
30
|
+
name:
|
|
31
|
+
type: [string, null] # INVALID - not supported
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## What DOES Work
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
User:
|
|
40
|
+
type: object
|
|
41
|
+
required: # This array controls EVERYTHING
|
|
42
|
+
- id # id is required -> string
|
|
43
|
+
- email # email is required -> string
|
|
44
|
+
# name is NOT here -> string | null
|
|
45
|
+
# age is NOT here -> number | null
|
|
46
|
+
properties:
|
|
47
|
+
id:
|
|
48
|
+
type: string
|
|
49
|
+
email:
|
|
50
|
+
type: string
|
|
51
|
+
name:
|
|
52
|
+
type: string
|
|
53
|
+
age:
|
|
54
|
+
type: number
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**TypeScript:**
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
export type User = {
|
|
61
|
+
id: string; // Required
|
|
62
|
+
email: string; // Required
|
|
63
|
+
name: string | null; // Nullable (not in required)
|
|
64
|
+
age: number | null; // Nullable (not in required)
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Scenarios
|
|
71
|
+
|
|
72
|
+
### All Properties Required
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
User:
|
|
76
|
+
type: object
|
|
77
|
+
required:
|
|
78
|
+
- id
|
|
79
|
+
- email
|
|
80
|
+
- name
|
|
81
|
+
- age
|
|
82
|
+
properties:
|
|
83
|
+
id: { type: string }
|
|
84
|
+
email: { type: string }
|
|
85
|
+
name: { type: string }
|
|
86
|
+
age: { type: number }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
export type User = {
|
|
91
|
+
id: string;
|
|
92
|
+
email: string;
|
|
93
|
+
name: string;
|
|
94
|
+
age: number;
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Some Properties Required
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
User:
|
|
102
|
+
type: object
|
|
103
|
+
required:
|
|
104
|
+
- id
|
|
105
|
+
- email
|
|
106
|
+
properties:
|
|
107
|
+
id: { type: string }
|
|
108
|
+
email: { type: string }
|
|
109
|
+
name: { type: string }
|
|
110
|
+
age: { type: number }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
export type User = {
|
|
115
|
+
id: string;
|
|
116
|
+
email: string;
|
|
117
|
+
name: string | null;
|
|
118
|
+
age: number | null;
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### No Properties Required (All Nullable)
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
User:
|
|
126
|
+
type: object
|
|
127
|
+
# No required array at all
|
|
128
|
+
properties:
|
|
129
|
+
id: { type: string }
|
|
130
|
+
email: { type: string }
|
|
131
|
+
name: { type: string }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
export type User = {
|
|
136
|
+
id: string | null;
|
|
137
|
+
email: string | null;
|
|
138
|
+
name: string | null;
|
|
139
|
+
};
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Empty Required Array (All Nullable)
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
User:
|
|
146
|
+
type: object
|
|
147
|
+
required: [] # Explicit empty array
|
|
148
|
+
properties:
|
|
149
|
+
id: { type: string }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
export type User = {
|
|
154
|
+
id: string | null;
|
|
155
|
+
};
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Nested Objects
|
|
161
|
+
|
|
162
|
+
Each nested object has its OWN `required` array:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
User:
|
|
166
|
+
type: object
|
|
167
|
+
required:
|
|
168
|
+
- id
|
|
169
|
+
- profile # profile object is required
|
|
170
|
+
properties:
|
|
171
|
+
id:
|
|
172
|
+
type: string
|
|
173
|
+
profile:
|
|
174
|
+
type: object
|
|
175
|
+
required:
|
|
176
|
+
- name # name inside profile is required
|
|
177
|
+
properties:
|
|
178
|
+
name:
|
|
179
|
+
type: string
|
|
180
|
+
bio:
|
|
181
|
+
type: string # NOT required inside profile
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
export type User = {
|
|
186
|
+
id: string;
|
|
187
|
+
profile: {
|
|
188
|
+
// profile is required (non-null)
|
|
189
|
+
name: string; // name is required inside profile
|
|
190
|
+
bio: string | null; // bio is nullable inside profile
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Arrays
|
|
198
|
+
|
|
199
|
+
The array itself follows `required` rules. Items have their own rules:
|
|
200
|
+
|
|
201
|
+
```yaml
|
|
202
|
+
Post:
|
|
203
|
+
type: object
|
|
204
|
+
required:
|
|
205
|
+
- id
|
|
206
|
+
- tags # tags array is required
|
|
207
|
+
properties:
|
|
208
|
+
id:
|
|
209
|
+
type: string
|
|
210
|
+
tags:
|
|
211
|
+
type: array
|
|
212
|
+
items:
|
|
213
|
+
type: string
|
|
214
|
+
comments: # NOT in required
|
|
215
|
+
type: array
|
|
216
|
+
items:
|
|
217
|
+
type: object
|
|
218
|
+
required:
|
|
219
|
+
- text
|
|
220
|
+
properties:
|
|
221
|
+
text: { type: string }
|
|
222
|
+
author: { type: string }
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
export type Post = {
|
|
227
|
+
id: string;
|
|
228
|
+
tags: string[]; // Required array
|
|
229
|
+
comments:
|
|
230
|
+
| {
|
|
231
|
+
// Nullable array
|
|
232
|
+
text: string;
|
|
233
|
+
author: string | null;
|
|
234
|
+
}[]
|
|
235
|
+
| null;
|
|
236
|
+
};
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## References
|
|
242
|
+
|
|
243
|
+
Referenced types maintain their own nullability. The reference's position in `required` controls if the reference itself is nullable:
|
|
244
|
+
|
|
245
|
+
```yaml
|
|
246
|
+
types:
|
|
247
|
+
Profile:
|
|
248
|
+
type: object
|
|
249
|
+
required: [bio]
|
|
250
|
+
properties:
|
|
251
|
+
bio: { type: string }
|
|
252
|
+
avatar: { type: string } # nullable inside Profile
|
|
253
|
+
|
|
254
|
+
User:
|
|
255
|
+
type: object
|
|
256
|
+
required:
|
|
257
|
+
- id
|
|
258
|
+
- mainProfile # This reference is required
|
|
259
|
+
properties:
|
|
260
|
+
id:
|
|
261
|
+
type: string
|
|
262
|
+
mainProfile:
|
|
263
|
+
$ref: '#/types/Profile'
|
|
264
|
+
backupProfile: # NOT in required
|
|
265
|
+
$ref: '#/types/Profile'
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
export type Profile = {
|
|
270
|
+
bio: string;
|
|
271
|
+
avatar: string | null;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export type User = {
|
|
275
|
+
id: string;
|
|
276
|
+
mainProfile: Profile; // Required reference
|
|
277
|
+
backupProfile: Profile | null; // Nullable reference
|
|
278
|
+
};
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Quick Reference
|
|
284
|
+
|
|
285
|
+
| Scenario | Result |
|
|
286
|
+
| ---------------------------- | ----------------------------------------------------- |
|
|
287
|
+
| Property in `required` array | `Type` |
|
|
288
|
+
| Property NOT in `required` | `Type \| null` |
|
|
289
|
+
| No `required` array | All properties `Type \| null` |
|
|
290
|
+
| `required: []` (empty) | All properties `Type \| null` |
|
|
291
|
+
| Nested object | Uses its own `required` array |
|
|
292
|
+
| Array items | Follow their own `required` rules |
|
|
293
|
+
| References | Reference position in `required` controls nullability |
|