diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index a1df5d2..a3cd867 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -28,6 +28,7 @@
- **Complex Types**: Union and intersection types, nested object structures, template literal types
- **Utility Types**: Built-in support for Pick, Omit, Partial, Required, Record, Readonly, and other TypeScript utility types
- **Advanced Features**: Conditional types, mapped types, keyof operators, indexed access types
+- **JavaScript Built-in Types**: Native support for Date type using TypeBox's JavaScript type system
- **Import Resolution**: Cross-file type dependencies with qualified naming and circular dependency handling
## Core Components
@@ -133,8 +134,9 @@ The handler system in ,
7. **Advanced Handlers**: , ,
8. **Function Handlers**:
-9. **Type Query Handlers**: ,
-10. **Access Handlers**: ,
+9. **JavaScript Type Handlers**: - Handles JavaScript built-in types like Date using TypeBox's extended type system
+10. **Type Query Handlers**: ,
+11. **Access Handlers**: ,
#### Readonly Type Handling
@@ -157,11 +159,20 @@ This dual approach ensures proper handling of both TypeScript readonly construct
- `type ReadonlyArray = readonly string[]` (array modifier)
- `type ReadonlyTuple = readonly [string, number]` (tuple modifier)
+#### JavaScript Built-in Type Support
+
+The system provides comprehensive support for JavaScript built-in types through specialized handlers:
+
+- **Date Type Handler**: The handles TypeScript's `Date` type references and converts them to TypeBox's `Type.Date()` schema
+- **Type Reference Registration**: JavaScript built-in types are registered in the `typeReferenceHandlers` map for O(1) lookup performance
+- **Extended Type System**: Leverages TypeBox's JavaScript type system for types that extend beyond standard JSON Schema
+
#### Handler Management
The class orchestrates all handlers through:
- **Handler Caching**: Caches handler instances for performance optimization
+- **Type Reference Mapping**: O(1) lookup for built-in types like Date, utility types like Partial, and other type references
- **Fallback System**: Provides fallback handlers for complex cases including readonly array modifiers
### Import Resolution
diff --git a/src/handlers/typebox/date-type-handler.ts b/src/handlers/typebox/date-type-handler.ts
new file mode 100644
index 0000000..bd95dcb
--- /dev/null
+++ b/src/handlers/typebox/date-type-handler.ts
@@ -0,0 +1,16 @@
+import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'
+import { makeTypeCall } from '@daxserver/validation-schema-codegen/utils/typebox-codegen-utils'
+import { Node, ts, TypeReferenceNode } from 'ts-morph'
+
+export class DateTypeHandler extends BaseTypeHandler {
+ canHandle(node: TypeReferenceNode): boolean {
+ const typeName = node.getTypeName()
+
+ return Node.isIdentifier(typeName) && typeName.getText() === 'Date'
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ handle(_node: TypeReferenceNode): ts.Expression {
+ return makeTypeCall('Date')
+ }
+}
diff --git a/src/handlers/typebox/typebox-type-handlers.ts b/src/handlers/typebox/typebox-type-handlers.ts
index c96f603..b1c359c 100644
--- a/src/handlers/typebox/typebox-type-handlers.ts
+++ b/src/handlers/typebox/typebox-type-handlers.ts
@@ -3,6 +3,7 @@ import { ArrayTypeHandler } from '@daxserver/validation-schema-codegen/handlers/
import { IntersectionTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/collection/intersection-type-handler'
import { TupleTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/collection/tuple-type-handler'
import { UnionTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/collection/union-type-handler'
+import { DateTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/date-type-handler'
import { FunctionTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/function-type-handler'
import { IndexedAccessTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/indexed-access-type-handler'
import { KeyOfTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/keyof-type-handler'
@@ -52,6 +53,7 @@ export class TypeBoxTypeHandlers {
const typeofTypeHandler = new TypeofTypeHandler()
const readonlyTypeHandler = new ReadonlyTypeHandler()
const readonlyArrayTypeHandler = new ReadonlyArrayTypeHandler()
+ const dateTypeHandler = new DateTypeHandler()
// O(1) lookup by SyntaxKind
this.syntaxKindHandlers.set(SyntaxKind.AnyKeyword, simpleTypeHandler)
@@ -83,6 +85,7 @@ export class TypeBoxTypeHandlers {
this.typeReferenceHandlers.set('Omit', omitTypeHandler)
this.typeReferenceHandlers.set('Required', requiredTypeHandler)
this.typeReferenceHandlers.set('Readonly', readonlyTypeHandler)
+ this.typeReferenceHandlers.set('Date', dateTypeHandler)
// Fallback handlers for complex cases
this.fallbackHandlers = [
diff --git a/tests/handlers/typebox/date-types.test.ts b/tests/handlers/typebox/date-types.test.ts
new file mode 100644
index 0000000..2f94961
--- /dev/null
+++ b/tests/handlers/typebox/date-types.test.ts
@@ -0,0 +1,113 @@
+import { createSourceFile, formatWithPrettier, generateFormattedCode } from '@test-fixtures/utils'
+import { beforeEach, describe, expect, test } from 'bun:test'
+import { Project } from 'ts-morph'
+
+describe('Date types', () => {
+ let project: Project
+
+ beforeEach(() => {
+ project = new Project()
+ })
+
+ test('without export', () => {
+ const sourceFile = createSourceFile(project, `type A = Date`)
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const A = Type.Date();
+
+ export type A = Static;
+ `),
+ )
+ })
+
+ test('with export', () => {
+ const sourceFile = createSourceFile(project, `export type A = Date`)
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const A = Type.Date();
+
+ export type A = Static;
+ `),
+ )
+ })
+
+ test('simple Date type alias', () => {
+ const sourceFile = createSourceFile(project, `type Timestamp = Date`)
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const Timestamp = Type.Date();
+
+ export type Timestamp = Static;
+ `),
+ )
+ })
+
+ test('Date in object property', () => {
+ const sourceFile = createSourceFile(
+ project,
+ `
+ interface User {
+ name: string;
+ createdAt: Date;
+ }
+ `,
+ )
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const User = Type.Object({
+ name: Type.String(),
+ createdAt: Type.Date(),
+ });
+
+ export type User = Static;
+ `),
+ )
+ })
+
+ test('Date in union type', () => {
+ const sourceFile = createSourceFile(project, `type Value = string | Date | number`)
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const Value = Type.Union([Type.String(), Type.Date(), Type.Number()]);
+
+ export type Value = Static;
+ `),
+ )
+ })
+
+ test('Date in array', () => {
+ const sourceFile = createSourceFile(project, `type Dates = Date[]`)
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const Dates = Type.Array(Type.Date());
+
+ export type Dates = Static;
+ `),
+ )
+ })
+
+ test('Date in function parameter and return type', () => {
+ const sourceFile = createSourceFile(
+ project,
+ `
+ function formatDate(date: Date): string {
+ return date.toString();
+ }
+ `,
+ )
+
+ expect(generateFormattedCode(sourceFile)).toBe(
+ formatWithPrettier(`
+ export const formatDate = Type.Function([Type.Date()], Type.String());
+
+ export type formatDate = Static;
+ `),
+ )
+ })
+})