@@ -40,20 +40,8 @@ export class ObjectFormatter implements TypeFormatter {
4040 return { type : "object" , additionalProperties : true } ;
4141 }
4242
43- // Special-case Date to a string with date-time format (match old behavior)
44- if ( type . symbol ?. name === "Date" && type . symbol ?. valueDeclaration ) {
45- // Check if this is the built-in Date type (not a user-defined type named "Date")
46- const sourceFile = type . symbol . valueDeclaration . getSourceFile ( ) ;
47-
48- if (
49- sourceFile . fileName . includes ( "lib." ) ||
50- sourceFile . fileName . includes ( "typescript/lib" ) ||
51- sourceFile . fileName . includes ( "ES2023.d.ts" ) ||
52- sourceFile . fileName . includes ( "DOM.d.ts" )
53- ) {
54- return { type : "string" , format : "date-time" } ;
55- }
56- }
43+ const builtin = this . lookupBuiltInSchema ( type ) ;
44+ if ( builtin ) return builtin ;
5745
5846 // Do not early-return for empty object types. Instead, try to enumerate
5947 // properties via the checker to allow type literals to surface members.
@@ -177,4 +165,38 @@ export class ObjectFormatter implements TypeFormatter {
177165
178166 return schema ;
179167 }
168+
169+ private lookupBuiltInSchema ( type : ts . Type ) : SchemaDefinition | undefined {
170+ const symbol = type . symbol ;
171+ if ( ! symbol ?. valueDeclaration ) return undefined ;
172+ const builtin = BUILT_IN_SCHEMAS . find ( ( entry ) => entry . test ( type ) ) ;
173+ return builtin ? structuredClone ( builtin . schema ) : undefined ;
174+ }
175+ }
176+
177+ type BuiltInSchemaEntry = {
178+ test : ( type : ts . Type ) => boolean ;
179+ schema : SchemaDefinition ;
180+ } ;
181+
182+ const BUILT_IN_SCHEMAS : BuiltInSchemaEntry [ ] = [
183+ {
184+ test : isNativeType ( "Date" ) ,
185+ schema : { type : "string" , format : "date-time" } ,
186+ } ,
187+ ] ;
188+
189+ function isNativeType ( name : string ) {
190+ return ( type : ts . Type ) => {
191+ const symbol = type . symbol ;
192+ if ( ! symbol || symbol . name !== name || ! symbol . valueDeclaration ) {
193+ return false ;
194+ }
195+ const sourceFile = symbol . valueDeclaration . getSourceFile ( ) ;
196+ const fileName = sourceFile . fileName ;
197+ return fileName . includes ( "lib." ) ||
198+ fileName . includes ( "typescript/lib" ) ||
199+ fileName . includes ( "ES2023.d.ts" ) ||
200+ fileName . includes ( "DOM.d.ts" ) ;
201+ } ;
180202}
0 commit comments