@@ -61,19 +61,28 @@ export function toSchemaType(
6161 schema ?:
6262 | OpenAPI . ReferenceObject
6363 | OpenAPI . SchemaObject ,
64+ coerceToString ?: boolean ,
6465) : string | undefined {
6566 if ( schema === undefined ) return undefined ;
6667 if ( "$ref" in schema ) return pascalCase ( schema . $ref . split ( "/" ) . pop ( ) ! ) ;
6768
6869 if ( "nullable" in schema && schema . nullable !== undefined ) {
69- const type = toSchemaType ( document , { ...schema , nullable : undefined } ) ;
70+ const type = toSchemaType (
71+ document ,
72+ { ...schema , nullable : undefined } ,
73+ coerceToString ,
74+ ) ;
7075 if ( type !== undefined ) return `${ type } |null` ;
7176 return "null" ;
7277 }
7378
7479 if ( schema . not !== undefined ) {
75- const type = toSchemaType ( document , { ...schema , not : undefined } ) ;
76- const exclude = toSchemaType ( document , schema . not ) ;
80+ const type = toSchemaType (
81+ document ,
82+ { ...schema , not : undefined } ,
83+ coerceToString ,
84+ ) ;
85+ const exclude = toSchemaType ( document , schema . not , coerceToString ) ;
7786 if ( type !== undefined && exclude !== undefined ) {
7887 return `Exclude<${ type } , ${ exclude } >` ;
7988 }
@@ -85,12 +94,13 @@ export function toSchemaType(
8594 const type = toSchemaType ( document , {
8695 ...schema ,
8796 additionalProperties : undefined ,
88- } ) ;
97+ } , coerceToString ) ;
8998 let additionalProperties ;
9099 if ( schema . additionalProperties !== true ) {
91100 additionalProperties = toSchemaType (
92101 document ,
93102 schema . additionalProperties ,
103+ coerceToString ,
94104 ) ;
95105 }
96106 if ( type !== undefined ) {
@@ -101,14 +111,14 @@ export function toSchemaType(
101111
102112 if ( schema . allOf ) {
103113 return schema . allOf
104- . map ( ( schema ) => toSchemaType ( document , schema ) )
114+ . map ( ( schema ) => toSchemaType ( document , schema , coerceToString ) )
105115 . filter ( Boolean )
106116 . join ( "&" ) ;
107117 }
108118
109119 if ( schema . oneOf ) {
110120 return schema . oneOf
111- . map ( ( schema ) => toSchemaType ( document , schema ) )
121+ . map ( ( schema ) => toSchemaType ( document , schema , coerceToString ) )
112122 . map ( ( type , _ , types ) => toSafeUnionString ( type , types ) )
113123 . filter ( Boolean )
114124 . join ( "|" ) ;
@@ -129,7 +139,7 @@ export function toSchemaType(
129139 }
130140
131141 return schema . anyOf
132- . map ( ( schema ) => toSchemaType ( document , schema ) )
142+ . map ( ( schema ) => toSchemaType ( document , schema , coerceToString ) )
133143 . map ( ( type , _ , types ) => toSafeUnionString ( type , types ) )
134144 . filter ( Boolean )
135145 . join ( "|" ) ;
@@ -141,11 +151,13 @@ export function toSchemaType(
141151
142152 switch ( schema . type ) {
143153 case "boolean" :
154+ if ( coerceToString ) return "`${boolean}`" ;
144155 return "boolean" ;
145156 case "string" :
146157 return "string" ;
147158 case "number" :
148159 case "integer" :
160+ if ( coerceToString ) return "`${number}`" ;
149161 return "number" ;
150162 case "object" : {
151163 if ( "properties" in schema && schema . properties !== undefined ) {
@@ -157,19 +169,24 @@ export function toSchemaType(
157169 . map ( ( [ property , type ] ) =>
158170 `${ escapeObjectKey ( property ) } ${
159171 schema . required ?. includes ( property ) ? "" : "?"
160- } :${ toSchemaType ( document , type ) } `
172+ } :${ toSchemaType ( document , type , coerceToString ) } `
161173 )
162174 . join ( ";" )
163175 } }`;
164176 }
177+
178+ if ( coerceToString ) return "Record<string, string>" ;
165179 return "Record<string, unknown>" ;
166180 }
167181 case "array" : {
168- const items = toSchemaType ( document , schema . items ) ;
182+ const items = toSchemaType ( document , schema . items , coerceToString ) ;
169183 if ( items !== undefined ) return `(${ items } )[]` ;
184+
185+ if ( coerceToString ) return "string[]" ;
170186 return "unknown[]" ;
171187 }
172188 case "null" :
189+ if ( coerceToString ) return "`${null}`" ;
173190 return "null" ;
174191 }
175192
@@ -300,25 +317,43 @@ export function createRequestBodyType(
300317 document : OpenAPI . Document ,
301318 contentType : string ,
302319 schema ?: OpenAPI . SchemaObject | OpenAPI . ReferenceObject ,
320+ options ?: Options ,
303321) : string {
304322 let type = "BodyInit" ;
305323
306324 switch ( contentType ) {
307- case "application/json" :
325+ case "application/json" : {
308326 type = `JSONString<${ toSchemaType ( document , schema ) ?? "unknown" } >` ;
309327 break ;
310- case "text/plain" :
328+ }
329+ case "text/plain" : {
311330 type = "string" ;
312331 break ;
313- case "multipart/form-data" :
332+ }
333+ case "multipart/form-data" : {
314334 type = "FormData" ;
315335 break ;
316- case "application/x-www-form-urlencoded" :
317- type = "URLSearchParams" ;
336+ }
337+ case "application/x-www-form-urlencoded" : {
338+ const schemaType = toSchemaType ( document , schema , true ) ;
339+ if ( schemaType !== undefined ) {
340+ const types = [ `URLSearchParamsString<${ schemaType } >` ] ;
341+
342+ // TODO: We don't yet support URLSearchParams with the --experimental-urlsearchparams flag
343+ if ( ! options ?. experimentalURLSearchParams ) {
344+ types . push ( `URLSearchParams<${ schemaType } >` ) ;
345+ }
346+
347+ return `(${ types . join ( "|" ) } )` ;
348+ } else {
349+ type = `URLSearchParams` ;
350+ }
318351 break ;
319- case "application/octet-stream" :
352+ }
353+ case "application/octet-stream" : {
320354 type = "ReadableStream | Blob | BufferSource" ;
321355 break ;
356+ }
322357 }
323358
324359 return type ;
@@ -385,7 +420,6 @@ export function toTemplateString(
385420 document : OpenAPI . Document ,
386421 pattern : string ,
387422 parameters : ParameterObjectMap ,
388- options : Options ,
389423) : string {
390424 let patternTemplateString = pattern ;
391425 let urlSearchParamsOptional = true ;
@@ -397,7 +431,9 @@ export function toTemplateString(
397431 urlSearchParamsOptional = false ;
398432 }
399433
400- const types = [ toSchemaType ( document , parameter . schema ) ?? "string" ] ;
434+ const types = [
435+ toSchemaType ( document , parameter . schema , true ) ?? "string" ,
436+ ] ;
401437 if ( parameter . allowEmptyValue === true ) types . push ( "true" ) ;
402438 urlSearchParamsRecord . push (
403439 `${ escapeObjectKey ( parameter . name ) } ${ ! parameter . required ? "?" : "" } : ${
@@ -414,15 +450,17 @@ export function toTemplateString(
414450 ) ;
415451 }
416452
417- const URLSearchParams = urlSearchParamsRecord . length > 0
418- ? options . experimentalURLSearchParams
419- ? `\${URLSearchParamsString<{${ urlSearchParamsRecord . join ( ";" ) } }>}`
420- : urlSearchParamsOptional
421- ? '${"" | `?${string}`}'
422- : "?${string}"
453+ const urlSearchParamsType = urlSearchParamsRecord . length > 0
454+ ? `URLSearchParamsString<{${ urlSearchParamsRecord . join ( ";" ) } }>`
455+ : undefined ;
456+
457+ const urlSearchParams = urlSearchParamsType
458+ ? urlSearchParamsOptional
459+ ? `\${\`?\${${ urlSearchParamsType } }\` | ""}`
460+ : `?\${${ urlSearchParamsType } }`
423461 : "" ;
424462
425- return `${ patternTemplateString } ${ URLSearchParams } ` ;
463+ return `${ patternTemplateString } ${ urlSearchParams } ` ;
426464}
427465
428466export function toHeadersInitType (
@@ -569,7 +607,7 @@ export function addOperationObject(
569607 doc . tags . push ( { tagName : "summary" , text : operation . summary . trim ( ) } ) ;
570608 }
571609
572- const path = toTemplateString ( document , pattern , parameters , options ) ;
610+ const path = toTemplateString ( document , pattern , parameters ) ;
573611
574612 const inputs = [ ] ;
575613
0 commit comments