Skip to content

Commit d274699

Browse files
committed
chore: wip
1 parent 5326f73 commit d274699

File tree

2 files changed

+215
-27
lines changed

2 files changed

+215
-27
lines changed

fixtures/input/example-0001.ts

Lines changed: 181 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { DtsGenerationConfig, DtsGenerationOption } from '@stacksjs/dtsx'
55
import { existsSync } from 'node:fs'
66
import { resolve } from 'node:path'
77

8+
// Testing some randomness
89
/**
910
* Example of const declaration
1011
*/
@@ -240,7 +241,7 @@ export * from './generate'
240241
export * from './types'
241242
export * from './utils'
242243

243-
// 1. Complex Generic Types
244+
// Complex Generic Types
244245
export interface ComplexGeneric<T extends Record<string, unknown>, K extends keyof T> {
245246
data: T
246247
key: K
@@ -249,15 +250,15 @@ export interface ComplexGeneric<T extends Record<string, unknown>, K extends key
249250
nested: Array<Partial<T>>
250251
}
251252

252-
// 2. Intersection and Union Types
253+
// Intersection and Union Types
253254
export type ComplexUnionIntersection =
254255
| (User & { role: 'admin' })
255256
| (Product & { category: string })
256257
& {
257258
metadata: Record<string, unknown>
258259
}
259260

260-
// 3. Mapped and Conditional Types
261+
// Mapped and Conditional Types
261262
export type ReadonlyDeep<T> = {
262263
readonly [P in keyof T]: T[P] extends object ? ReadonlyDeep<T[P]> : T[P]
263264
}
@@ -268,7 +269,7 @@ export type ConditionalResponse<T> = T extends Array<infer U>
268269
? ApiResponse<T>
269270
: ApiResponse<string>
270271

271-
// 4. Complex Function Overloads
272+
// Complex Function Overloads
272273
export function processData(data: string): string
273274
export function processData(data: number): number
274275
export function processData(data: boolean): boolean
@@ -277,23 +278,182 @@ export function processData(data: unknown): unknown {
277278
return data
278279
}
279280

280-
// 5. Nested Object Types with Methods
281-
export const complexObject = {
282-
handlers: {
283-
async onSuccess<T>(data: T): Promise<void> {
284-
console.log(data)
285-
},
286-
onError(error: Error & { code?: number }): never {
287-
throw error
288-
}
289-
},
290-
utils: {
291-
formatters: {
292-
date: (input: Date) => input.toISOString(),
293-
currency: (amount: number, currency = 'USD') =>
294-
new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount)
295-
}
296-
}
281+
export type EventType = 'click' | 'focus' | 'blur'
282+
export type ElementType = 'button' | 'input' | 'form'
283+
export type EventHandler = `on${Capitalize<EventType>}${Capitalize<ElementType>}`
284+
285+
// Recursive Types
286+
export type RecursiveObject = {
287+
id: string
288+
children?: RecursiveObject[]
289+
parent?: RecursiveObject
290+
metadata: Record<string, unknown>
291+
}
292+
293+
// Complex Arrays and Tuples
294+
export const complexArrays = {
295+
matrix: [
296+
[1, 2, [3, 4, [5, 6]]],
297+
['a', 'b', ['c', 'd']],
298+
[true, [false, [true]]],
299+
],
300+
tuples: [
301+
[1, 'string', true] as const,
302+
['literal', 42, false] as const,
303+
],
304+
// TODO: get this part to generate correctly
305+
// mixedArrays: [
306+
// new Date(),
307+
// Promise.resolve('async'),
308+
// async () => 'result',
309+
// function* generator() { yield 42 },
310+
// ]
311+
}
312+
313+
// TODO: Nested Object Types with Methods
314+
// export const complexObject = {
315+
// handlers: {
316+
// async onSuccess<T>(data: T): Promise<void> {
317+
// console.log(data)
318+
// },
319+
// onError(error: Error & { code?: number }): never {
320+
// throw error
321+
// }
322+
// },
323+
// utils: {
324+
// formatters: {
325+
// date: (input: Date) => input.toISOString(),
326+
// currency: (amount: number, currency = 'USD') =>
327+
// new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount)
328+
// }
329+
// }
330+
// }
331+
332+
// TODO: Default Type Parameters
333+
// export interface DefaultGeneric<
334+
// T = string,
335+
// K extends keyof any = string,
336+
// V extends Record<K, T> = Record<K, T>
337+
// > {
338+
// key: K
339+
// value: T
340+
// record: V
341+
// }
342+
343+
// TODO: Method Decorators and Metadata
344+
// export const methodDecorator = (
345+
// target: any,
346+
// propertyKey: string,
347+
// descriptor: PropertyDescriptor
348+
// ) => {
349+
// return {
350+
// ...descriptor,
351+
// enumerable: true,
352+
// }
353+
// }
354+
355+
// Complex Async Patterns
356+
// due to isolatedDeclarations, we can assume the return type here
357+
// export async function* complexAsyncGenerator(): any {
358+
// const results = await Promise.all([
359+
// fetchUsers(),
360+
// getProduct(1),
361+
// authenticate('user', 'pass'),
362+
// ])
363+
364+
// for (const result of results) {
365+
// yield result
366+
// }
367+
// }
368+
369+
// Type Assertions and Guards
370+
// export function isUser(value: unknown): value is User {
371+
// return (
372+
// typeof value === 'object'
373+
// && value !== null
374+
// && 'id' in value
375+
// && 'email' in value
376+
// )
377+
// }
378+
379+
// Branded Types
380+
export type UserId = string & { readonly __brand: unique symbol }
381+
export type ProductId = number & {
382+
readonly __brand: unique symbol
383+
}
384+
385+
// TODO: Complex Error Handling
386+
// export class CustomError extends Error {
387+
// constructor(
388+
// message: string,
389+
// public readonly code: number,
390+
// public readonly metadata: Record<string, unknown>
391+
// ) {
392+
// super(message)
393+
// this.name = 'CustomError'
394+
// }
395+
// }
396+
397+
// TODO: Module Augmentation
398+
// declare module '@stacksjs/dtsx' {
399+
// interface DtsGenerationConfig {
400+
// customPlugins?: Array<{
401+
// name: string
402+
// transform: (code: string) => string
403+
// }>
404+
// }
405+
// }
406+
407+
// Utility Type Implementations
408+
export type DeepPartial<T> = T extends object ? {
409+
[P in keyof T]?: DeepPartial<T[P]>
410+
} : T
411+
412+
export type DeepRequired<T> = T extends object ? {
413+
[P in keyof T]-?: DeepRequired<T[P]>
414+
} : T
415+
416+
// TODO: Complex Constants with Type Inference
417+
// export const CONFIG_MAP = {
418+
// development: {
419+
// features: {
420+
// auth: {
421+
// providers: ['google', 'github'] as const,
422+
// settings: { timeout: 5000, retries: 3 }
423+
// }
424+
// }
425+
// },
426+
// production: {
427+
// features: {
428+
// auth: {
429+
// providers: ['google', 'github', 'microsoft'] as const,
430+
// settings: { timeout: 3000, retries: 5 }
431+
// }
432+
// }
433+
// }
434+
// } as const
435+
436+
// Polymorphic Types
437+
export type PolymorphicComponent<P = {}> = {
438+
<C extends React.ElementType>(
439+
props: { as?: C } & Omit<React.ComponentPropsWithRef<C>, keyof P> & P
440+
): React.ReactElement | null
441+
}
442+
443+
// TODO: Type Inference in Functions
444+
// export function createApi<T extends Record<string, (...args: any[]) => any>>(
445+
// endpoints: T
446+
// ): { [K in keyof T]: ReturnType<T[K]> extends Promise<infer R> ? R : ReturnType<T[K]> } {
447+
// return {} as any
448+
// }
449+
450+
// Complex Index Types
451+
export type DynamicRecord<K extends PropertyKey> = {
452+
[P in K]: P extends number
453+
? Array<unknown>
454+
: P extends string
455+
? Record<string, unknown>
456+
: never
297457
}
298458

299459
export default dts

fixtures/output/example-0001.d.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,41 @@ export declare function processData(data: number): number;
120120
export declare function processData(data: boolean): boolean;
121121
export declare function processData<T extends object>(data: T): T;
122122
export declare function processData(data: unknown): unknown;
123-
export declare const complexObject: {
124-
handlers: <T>(data: T) => Promise<void> {
125-
console.log(data)
126-
},
127-
onError(error: Error & { code?: number }): never {
128-
throw error;
123+
export declare type EventType = 'click' | 'focus' | 'blur';
124+
export declare type ElementType = 'button' | 'input' | 'form';
125+
export declare type EventHandler = `on${Capitalize<EventType>}${Capitalize<ElementType>}`;
126+
export declare type RecursiveObject = {
127+
id: string
128+
children?: RecursiveObject[]
129+
parent?: RecursiveObject
130+
metadata: Record<string, unknown>
131+
}
132+
export declare const complexArrays: {
133+
matrix: Array<Array<1 | 2 | Array<3 | 4 | Array<5 | 6>>> | Array<'a' | 'b' | Array<'c' | 'd'>> | Array<true | Array<false | Array<true>>>>;
134+
tuples: Array<Array<1 | 'string' | true> | Array<'literal' | 42 | false>>;
129135
};
136+
export declare type UserId = string & { readonly __brand: unique symbol };
137+
export declare type ProductId = number & {
138+
readonly __brand: unique symbol
139+
}
140+
export declare type DeepPartial<T> = T extends object ? {
141+
[P in keyof T]?: DeepPartial<T[P]>
142+
} : T
143+
export declare type DeepRequired<T> = T extends object ? {
144+
[P in keyof T]-?: DeepRequired<T[P]>
145+
} : T
146+
export declare type PolymorphicComponent<P = {}> = {
147+
<C extends React.ElementType>(
148+
props: { as?: C } & Omit<React.ComponentPropsWithRef<C>, keyof P> & P
149+
): React.ReactElement | null
150+
}
151+
export type DynamicRecord<K extends PropertyKey> = {
152+
[P in K]: P extends number
153+
? Array<unknown>
154+
: P extends string
155+
? Record<string, unknown>
156+
: never
157+
}
130158

131159
export { generate, dtsConfig }
132160
export type { DtsGenerationOption }

0 commit comments

Comments
 (0)