q-type 0.1.2

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.
@@ -0,0 +1,612 @@
1
+ /**
2
+ * Clase base abstracta para todo esquema de Qtype.
3
+ *
4
+ * Cada esquema concreto (QString, QNumber, QSchema, etc.) extiende esta clase
5
+ * e implementa {@link decode} y {@link encode}.
6
+ *
7
+ * @typeParam T - El tipo TypeScript que representa este esquema.
8
+ */
9
+ declare abstract class QType<T> {
10
+ /** Discriminante de runtime que identifica el tipo de esquema. */
11
+ abstract readonly kind: string;
12
+ /**
13
+ * Decodifica un string crudo en el valor tipado {@link T}.
14
+ *
15
+ * @throws {QtypeParseError} si el string no es válido.
16
+ */
17
+ abstract decode(raw: string, ctx: DecodeContext): T;
18
+ /**
19
+ * Codifica un valor tipado {@link T} de vuelta a su representación en string.
20
+ */
21
+ abstract encode(value: T, opts?: EncodeOptions): string;
22
+ }
23
+ /** Contexto que se propaga durante la decodificación para generar mensajes de error precisos. */
24
+ interface DecodeContext {
25
+ readonly key: string;
26
+ readonly path: string;
27
+ readonly raw: string;
28
+ }
29
+ /** Opciones de codificación compartidas por todos los esquemas. */
30
+ interface EncodeOptions {
31
+ /** Extiende la salida a al menos N segmentos (solo aplica en {@link QSchema}). */
32
+ length?: number;
33
+ }
34
+ /**
35
+ * Extrae el tipo TypeScript a partir de una instancia de esquema.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const Name = q.String();
40
+ * type Name = Static<typeof Name>; // string
41
+ * ```
42
+ */
43
+ type Static<T extends QType<any>> = T extends QType<infer U> ? U : never;
44
+ /** Mapa de propiedades que define la forma de un {@link QObject} o {@link QSchema}. */
45
+ type SchemaProps = Record<string, QType<any>>;
46
+ /**
47
+ * Desenvuelve {@link QPositioned}`<T>` → `T`.
48
+ *
49
+ * Para cualquier otro esquema se comporta como {@link Static}.
50
+ *
51
+ * @internal — Usado por {@link FilterAt}.
52
+ */
53
+ type UnwrapAt<T extends QType<any>> = T extends {
54
+ kind: "positioned";
55
+ decode(raw: string, ctx: DecodeContext): infer U;
56
+ } ? U : Static<T>;
57
+ /**
58
+ * Tipo resultante de un {@link QSchema}: un objeto cuyas claves son las
59
+ * propiedades declaradas y cuyos valores son los tipos decodificados.
60
+ */
61
+ type FilterAt<T extends SchemaProps> = { [K in keyof T] : UnwrapAt<T[K]> };
62
+ /**
63
+ * Error lanzado cuando el parseo de un segmento falla.
64
+ *
65
+ * Incluye el contexto completo (key, path, rawValue) para facilitar el debug.
66
+ */
67
+ declare class QtypeParseError extends Error {
68
+ readonly key: string;
69
+ readonly path: string;
70
+ readonly rawValue: string;
71
+ constructor(message: string, ctx: DecodeContext);
72
+ }
73
+ /**
74
+ * Resultado de {@link QSchema.safeParse} y {@link QUnion.safeParse}.
75
+ *
76
+ * `success: true` con `data`, o `success: false` con `error`.
77
+ */
78
+ type SafeResult<T> = {
79
+ success: true;
80
+ data: T;
81
+ } | {
82
+ success: false;
83
+ error: QtypeParseError;
84
+ };
85
+ /**
86
+ * Esquema para strings.
87
+ *
88
+ * Lanza {@link QtypeParseError} si el segmento está vacío.
89
+ * Para permitir strings vacíos usa {@link QOptional} o {@link QDefault}.
90
+ */
91
+ declare class QString extends QType<string> {
92
+ readonly kind = "string";
93
+ decode(raw: string, ctx: DecodeContext): string;
94
+ encode(value: string, _opts?: EncodeOptions): string;
95
+ }
96
+ /**
97
+ * Esquema para números de punto flotante.
98
+ *
99
+ * Acepta cualquier string que `Number()` pueda parsear.
100
+ * Lanza {@link QtypeParseError} si está vacío o no es un número válido.
101
+ */
102
+ declare class QNumber extends QType<number> {
103
+ readonly kind = "number";
104
+ decode(raw: string, ctx: DecodeContext): number;
105
+ encode(value: number, _opts?: EncodeOptions): string;
106
+ }
107
+ /**
108
+ * Esquema para números enteros.
109
+ *
110
+ * Usa {@link parseInt} con la base especificada (por defecto 10).
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * q.Integer() // base 10, decimal
115
+ * q.Integer(16) // base 16, hexadecimal
116
+ * ```
117
+ */
118
+ declare class QInteger extends QType<number> {
119
+ readonly kind = "integer";
120
+ private readonly radix;
121
+ constructor(radix?: number);
122
+ decode(raw: string, ctx: DecodeContext): number;
123
+ encode(value: number, _opts?: EncodeOptions): string;
124
+ }
125
+ /**
126
+ * Esquema para valores booleanos.
127
+ *
128
+ * Por defecto reconoce `"1"`, `"true"`, `"Y"`, `"y"` como `true`.
129
+ * Cualquier otro valor (incluyendo vacío) es `false`.
130
+ * La lista de valores truthy es configurable.
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * q.Boolean() // truthy: ["1", "true", "Y", "y"]
135
+ * q.Boolean(["S", "s", "SI", "si"]) // truthy personalizado
136
+ * ```
137
+ */
138
+ declare class QBoolean extends QType<boolean> {
139
+ readonly kind = "boolean";
140
+ private readonly truthy;
141
+ constructor(truthy?: readonly string[]);
142
+ decode(raw: string, ctx: DecodeContext): boolean;
143
+ encode(value: boolean, _opts?: EncodeOptions): string;
144
+ }
145
+ /**
146
+ * Esquema para fechas.
147
+ *
148
+ * Soporta dos formatos:
149
+ * - `"iso"` (por defecto): usa `new Date(str)` y serializa con `toISOString()`.
150
+ * - `"yyyyMMdd"`: parsea y serializa manualmente en zona horaria local.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * q.Date() // formato ISO
155
+ * q.Date("yyyyMMdd") // formato compacto de 8 dígitos
156
+ * ```
157
+ */
158
+ declare class QDate extends QType<Date> {
159
+ readonly kind = "date";
160
+ private readonly format;
161
+ constructor(format?: "iso" | "yyyyMMdd");
162
+ decode(raw: string, ctx: DecodeContext): Date;
163
+ encode(value: Date, _opts?: EncodeOptions): string;
164
+ }
165
+ /**
166
+ * Esquema que solo acepta un valor literal exacto.
167
+ *
168
+ * Útil como discriminador en uniones (ver {@link QUnion.match}).
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * q.Literal("00") // solo acepta el string "00"
173
+ * q.Literal(42) // solo acepta el número 42
174
+ * ```
175
+ */
176
+ declare class QLiteral<T extends string | number> extends QType<T> {
177
+ readonly kind = "literal";
178
+ readonly value: T;
179
+ constructor(value: T);
180
+ decode(raw: string, ctx: DecodeContext): T;
181
+ encode(value: T, _opts?: EncodeOptions): string;
182
+ }
183
+ /**
184
+ * Esquema que restringe el valor a un conjunto finito de strings.
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * q.Enum(["pendiente", "procesado", "rechazado"])
189
+ * ```
190
+ */
191
+ declare class QEnum<T extends readonly string[]> extends QType<T[number]> {
192
+ readonly kind = "enum";
193
+ readonly values: T;
194
+ constructor(values: T);
195
+ decode(raw: string, ctx: DecodeContext): T[number];
196
+ encode(value: T[number], _opts?: EncodeOptions): string;
197
+ }
198
+ /**
199
+ * Convierte un esquema en opcional.
200
+ *
201
+ * Un segmento vacío (`""`) se decodifica como `undefined`.
202
+ * Al codificar, `undefined` se serializa como `""`.
203
+ */
204
+ declare class QOptional<T extends QType<any>> extends QType<Static<T> | undefined> {
205
+ readonly kind = "optional";
206
+ readonly inner: T;
207
+ constructor(schema: T);
208
+ decode(raw: string, ctx: DecodeContext): Static<T> | undefined;
209
+ encode(value: Static<T> | undefined, _opts?: EncodeOptions): string;
210
+ }
211
+ /**
212
+ * Convierte un esquema en nullable.
213
+ *
214
+ * Un segmento vacío (`""`) se decodifica como `null`.
215
+ * Al codificar, `null` se serializa como `""`.
216
+ */
217
+ declare class QNullable<T extends QType<any>> extends QType<Static<T> | null> {
218
+ readonly kind = "nullable";
219
+ readonly inner: T;
220
+ constructor(schema: T);
221
+ decode(raw: string, ctx: DecodeContext): Static<T> | null;
222
+ encode(value: Static<T> | null, _opts?: EncodeOptions): string;
223
+ }
224
+ /**
225
+ * Asigna un valor por defecto cuando el segmento está vacío.
226
+ *
227
+ * A diferencia de {@link QOptional}, el tipo de salida **no** incluye `undefined`.
228
+ * Si el segmento no está vacío, se decodifica normalmente con el esquema interno.
229
+ */
230
+ declare class QDefault<T extends QType<any>> extends QType<Static<T>> {
231
+ readonly kind = "default";
232
+ readonly inner: T;
233
+ readonly defaultValue: Static<T>;
234
+ constructor(schema: T, defaultValue: Static<T>);
235
+ decode(raw: string, ctx: DecodeContext): Static<T>;
236
+ encode(value: Static<T>, _opts?: EncodeOptions): string;
237
+ }
238
+ /**
239
+ * Aplica una transformación bidireccional sobre otro esquema.
240
+ *
241
+ * Permite convertir entre la representación en el wire y el tipo en la app.
242
+ *
243
+ * @typeParam A - Esquema de entrada (tipo wire).
244
+ * @typeParam B - Tipo de salida en la app.
245
+ *
246
+ * @example
247
+ * ```ts
248
+ * // wire: centavos (entero), app: dólares (flotante)
249
+ * q.Transform(q.Number(), cents => cents / 100, dollars => dollars * 100)
250
+ * ```
251
+ */
252
+ declare class QTransform<
253
+ A extends QType<any>,
254
+ B
255
+ > extends QType<B> {
256
+ readonly kind = "transform";
257
+ readonly inner: A;
258
+ private readonly decodeFn;
259
+ private readonly encodeFn;
260
+ constructor(schema: A, decodeFn: (a: Static<A>) => B, encodeFn: (b: B) => Static<A>);
261
+ decode(raw: string, ctx: DecodeContext): B;
262
+ encode(value: B, opts?: EncodeOptions): string;
263
+ }
264
+ /**
265
+ * Asigna una posición explícita a un campo dentro de un {@link QSchema}.
266
+ *
267
+ * Se crea mediante {@link q.at}.
268
+ * A nivel de tipos es transparente: el tipo de salida es el del esquema interno.
269
+ */
270
+ declare class QPositioned<T extends QType<any>> extends QType<Static<T>> {
271
+ readonly kind = "positioned";
272
+ readonly index: number;
273
+ readonly inner: T;
274
+ constructor(index: number, schema: T);
275
+ decode(raw: string, ctx: DecodeContext): Static<T>;
276
+ encode(value: Static<T>, opts?: EncodeOptions): string;
277
+ }
278
+ /**
279
+ * Verifica en runtime si un esquema es una instancia de {@link QPositioned}.
280
+ */
281
+ declare function isPositioned(schema: QType<any>): schema is QPositioned<any>;
282
+ /**
283
+ * Lista delimitada de elementos homogéneos dentro de un mismo segmento.
284
+ *
285
+ * El separador por defecto es `";"`.
286
+ * Un segmento vacío (`""`) produce un arreglo vacío `[]`.
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * q.Array(q.String(), { sep: ";" })
291
+ * // "a;b;c" → ["a", "b", "c"]
292
+ * ```
293
+ */
294
+ declare class QArray<T extends QType<any>> extends QType<Static<T>[]> {
295
+ readonly kind = "array";
296
+ readonly element: T;
297
+ private readonly sep;
298
+ constructor(schema: T, opts?: {
299
+ sep?: string;
300
+ });
301
+ decode(raw: string, ctx: DecodeContext): Static<T>[];
302
+ encode(value: Static<T>[], _opts?: EncodeOptions): string;
303
+ }
304
+ /**
305
+ * Pares clave:valor delimitados dentro de un mismo segmento.
306
+ *
307
+ * Los separadores por defecto son:
308
+ * - Entre pares: `";"`
309
+ * - Entre clave y valor: `":"`
310
+ *
311
+ * Las claves no declaradas en el esquema producen error.
312
+ * Las claves declaradas pero ausentes se decodifican con string vacío
313
+ * (permitiendo que {@link QOptional}, {@link QNullable} y {@link QDefault}
314
+ * manejen el caso).
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * q.Object({ name: q.String(), age: q.Integer() }, { sep: ";", kvSep: ":" })
319
+ * // "name:John;age:30" → { name: "John", age: 30 }
320
+ * ```
321
+ */
322
+ declare class QObject<T extends SchemaProps> extends QType<{ [K in keyof T] : Static<T[K]> }> {
323
+ readonly kind = "object";
324
+ readonly properties: T;
325
+ private readonly sep;
326
+ private readonly kvSep;
327
+ constructor(properties: T, opts?: {
328
+ sep?: string;
329
+ kvSep?: string;
330
+ });
331
+ decode(raw: string, ctx: DecodeContext): { [K in keyof T] : Static<T[K]> };
332
+ encode(value: { [K in keyof T] : Static<T[K]> }, _opts?: EncodeOptions): string;
333
+ }
334
+ /**
335
+ * Lista posicional de largo fijo con esquemas heterogéneos.
336
+ *
337
+ * Cada posición tiene su propio esquema. El número de elementos en el wire
338
+ * debe ser al menos igual al número de esquemas declarados.
339
+ * El separador por defecto es `";"`.
340
+ *
341
+ * @example
342
+ * ```ts
343
+ * q.Tuple([q.String(), q.Integer(), q.String()], { sep: ";" })
344
+ * // "John;30;NYC" → ["John", 30, "NYC"]
345
+ * ```
346
+ */
347
+ declare class QTuple<T extends QType<any>[]> extends QType<{ [K in keyof T] : Static<T[K]> }> {
348
+ readonly kind = "tuple";
349
+ readonly items: T;
350
+ private readonly sep;
351
+ constructor(items: [...T], opts?: {
352
+ sep?: string;
353
+ });
354
+ decode(raw: string, ctx: DecodeContext): { [K in keyof T] : Static<T[K]> };
355
+ encode(value: { [K in keyof T] : Static<T[K]> }, _opts?: EncodeOptions): string;
356
+ }
357
+ /**
358
+ * Esquema principal: protocolo delimitado por pipes de nivel superior.
359
+ *
360
+ * Es el tipo de esquema más común. Define un mensaje completo donde cada
361
+ * campo ocupa una posición fija separada por `delimiter` (por defecto `"|"`).
362
+ *
363
+ * ### Posiciones
364
+ *
365
+ * Por defecto, las posiciones se asignan secuencialmente según el orden de
366
+ * las claves. Usa {@link q.at} para asignar posiciones explícitas y crear
367
+ * layouts sparse (ej. declarar 7 campos de 200 posiciones).
368
+ *
369
+ * ### Métodos de conveniencia
370
+ *
371
+ * - {@link parse}: decodifica un string crudo, lanza {@link QtypeParseError} si falla.
372
+ * - {@link safeParse}: igual que `parse` pero retorna `{ success, data/error }` sin lanzar.
373
+ * - {@link serialize}: codifica un objeto de vuelta a string.
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * const Msg = q.Schema({
378
+ * tipo: q.String(),
379
+ * monto: q.Number(),
380
+ * });
381
+ *
382
+ * Msg.parse("105|150.00"); // { tipo: "105", monto: 150 }
383
+ * Msg.serialize({ tipo: "105", monto: 150 }); // "105|150"
384
+ * ```
385
+ */
386
+ declare class QSchema<T extends SchemaProps> extends QType<FilterAt<T>> {
387
+ readonly kind = "schema";
388
+ readonly properties: T;
389
+ private readonly delimiter;
390
+ private readonly positions;
391
+ constructor(properties: T, opts?: {
392
+ delimiter?: string;
393
+ strictLength?: boolean;
394
+ });
395
+ /**
396
+ * Decodifica un mensaje completo.
397
+ *
398
+ * @throws {QtypeParseError} si el mensaje no es válido.
399
+ */
400
+ parse(raw: string): FilterAt<T>;
401
+ /**
402
+ * Decodifica un mensaje completo sin lanzar excepciones.
403
+ *
404
+ * Retorna `{ success: true, data }` o `{ success: false, error }`.
405
+ */
406
+ safeParse(raw: string): SafeResult<FilterAt<T>>;
407
+ decode(raw: string, ctx: DecodeContext): FilterAt<T>;
408
+ encode(value: FilterAt<T>, opts?: EncodeOptions): string;
409
+ /**
410
+ * Alias de {@link encode} para mayor claridad semántica.
411
+ */
412
+ serialize(value: FilterAt<T>, opts?: EncodeOptions): string;
413
+ }
414
+ /**
415
+ * Unión de esquemas: prueba cada variante en orden y retorna la primera
416
+ * que decodifique correctamente.
417
+ *
418
+ * ### Modo no discriminado (por defecto)
419
+ *
420
+ * Prueba cada variante secuencialmente al decodificar. La primera que no
421
+ * lance error gana.
422
+ *
423
+ * ### Modo discriminado
424
+ *
425
+ * Cuando se provee `discriminator`, {@link match} permite seleccionar la
426
+ * variante correcta antes de decodificar, según el valor de un campo
427
+ * {@link QLiteral} o {@link QEnum} en el {@link QSchema}.
428
+ *
429
+ * @example
430
+ * ```ts
431
+ * const Msg = q.Union([
432
+ * q.Schema({ tipo: q.Literal("00"), id: q.String() }),
433
+ * q.Schema({ tipo: q.Literal("01"), id: q.String(), status: q.String() }),
434
+ * ]);
435
+ *
436
+ * Msg.parse("00|CPN-1"); // variante 00
437
+ * Msg.parse("01|CPN-2|ok"); // variante 01
438
+ * ```
439
+ */
440
+ declare class QUnion<T extends QType<any>[]> extends QType<Static<T[number]>> {
441
+ readonly kind = "union";
442
+ readonly variants: [...T];
443
+ private readonly discriminator?;
444
+ constructor(variants: [...T], opts?: {
445
+ discriminator?: string;
446
+ });
447
+ /**
448
+ * Decodifica un mensaje probando cada variante en orden.
449
+ *
450
+ * @throws {QtypeParseError} si ninguna variante coincide.
451
+ */
452
+ parse(raw: string): Static<T[number]>;
453
+ /**
454
+ * Versión segura de {@link parse} que no lanza excepciones.
455
+ */
456
+ safeParse(raw: string): {
457
+ success: true;
458
+ data: Static<T[number]>;
459
+ } | {
460
+ success: false;
461
+ error: QtypeParseError;
462
+ };
463
+ decode(raw: string, ctx: DecodeContext): Static<T[number]>;
464
+ encode(value: Static<T[number]>, opts?: EncodeOptions): string;
465
+ /**
466
+ * Alias de {@link encode} para mayor claridad semántica.
467
+ */
468
+ serialize(value: Static<T[number]>, opts?: EncodeOptions): string;
469
+ /**
470
+ * Para uniones discriminadas, retorna la variante cuyo campo discriminador
471
+ * coincide con `value`.
472
+ *
473
+ * El discriminador debe ser un {@link QLiteral} o {@link QEnum} dentro de
474
+ * un {@link QSchema}.
475
+ *
476
+ * @returns La variante coincidente, o `undefined` si no hay coincidencia.
477
+ */
478
+ match(value: string): QType<any> | undefined;
479
+ }
480
+ /**
481
+ * Namespace `q` — fábrica de esquemas.
482
+ *
483
+ * Cada método retorna una instancia de esquema lista para usar en
484
+ * {@link QSchema.parse}, {@link QSchema.serialize}, etc.
485
+ *
486
+ * @example
487
+ * ```ts
488
+ * import { q, type Static } from "qtype";
489
+ *
490
+ * const Msg = q.Schema({
491
+ * tipo: q.String(),
492
+ * monto: q.Number(),
493
+ * activo: q.Boolean(),
494
+ * });
495
+ *
496
+ * type Msg = Static<typeof Msg>;
497
+ * // { tipo: string; monto: number; activo: boolean }
498
+ * ```
499
+ */
500
+ declare const q: {
501
+ /** Esquema para strings. El segmento vacío lanza error. */
502
+ String: () => QString;
503
+ /** Esquema para números de punto flotante. */
504
+ Number: () => QNumber;
505
+ /**
506
+ * Esquema para números enteros.
507
+ *
508
+ * @param radix - Base numérica (por defecto 10).
509
+ */
510
+ Integer: (radix?: number) => QInteger;
511
+ /**
512
+ * Esquema para booleanos.
513
+ *
514
+ * @param truthy - Lista de strings que se interpretan como `true`.
515
+ * Por defecto `["1", "true", "Y", "y"]`.
516
+ */
517
+ Boolean: (truthy?: readonly string[]) => QBoolean;
518
+ /**
519
+ * Esquema para fechas.
520
+ *
521
+ * @param format - `"iso"` (por defecto) o `"yyyyMMdd"`.
522
+ */
523
+ Date: (format?: "iso" | "yyyyMMdd") => QDate;
524
+ /** Esquema que solo acepta un valor literal exacto. */
525
+ Literal: <T extends string | number>(value: T) => QLiteral<T>;
526
+ /** Esquema que restringe el valor a un conjunto de strings. */
527
+ Enum: <T extends readonly string[]>(values: T) => QEnum<T>;
528
+ /**
529
+ * Lista delimitada de elementos homogéneos.
530
+ *
531
+ * @param schema - Esquema de cada elemento.
532
+ * @param opts.sep - Separador entre elementos (por defecto `";"`).
533
+ */
534
+ Array: <T extends QType<any>>(schema: T, opts?: {
535
+ sep?: string;
536
+ }) => QArray<T>;
537
+ /**
538
+ * Pares clave:valor delimitados.
539
+ *
540
+ * @param props - Definición de las propiedades.
541
+ * @param opts.sep - Separador entre pares (por defecto `";"`).
542
+ * @param opts.kvSep - Separador clave-valor (por defecto `":"`).
543
+ */
544
+ Object: <T extends SchemaProps>(props: T, opts?: {
545
+ sep?: string;
546
+ kvSep?: string;
547
+ }) => QObject<T>;
548
+ /**
549
+ * Tupla posicional de largo fijo con esquemas heterogéneos.
550
+ *
551
+ * @param items - Arreglo de esquemas, uno por posición.
552
+ * @param opts.sep - Separador entre elementos (por defecto `";"`).
553
+ */
554
+ Tuple: <T extends QType<any>[]>(items: [...T], opts?: {
555
+ sep?: string;
556
+ }) => QTuple<T>;
557
+ /**
558
+ * Esquema principal: mensaje delimitado por pipes.
559
+ *
560
+ * @param props - Definición de los campos del mensaje.
561
+ * @param opts.delimiter - Separador entre campos (por defecto `"|"`).
562
+ */
563
+ Schema: <T extends SchemaProps>(props: T, opts?: {
564
+ delimiter?: string;
565
+ strictLength?: boolean;
566
+ }) => QSchema<T>;
567
+ /** Convierte un esquema en opcional. Vacío → `undefined`. */
568
+ Optional: <T extends QType<any>>(schema: T) => QOptional<T>;
569
+ /** Convierte un esquema en nullable. Vacío → `null`. */
570
+ Nullable: <T extends QType<any>>(schema: T) => QNullable<T>;
571
+ /**
572
+ * Asigna un valor por defecto cuando el segmento está vacío.
573
+ *
574
+ * A diferencia de {@link Optional}, el tipo de salida no incluye `undefined`.
575
+ */
576
+ Default: <T extends QType<any>>(schema: T, defaultValue: Static<T>) => QDefault<T>;
577
+ /**
578
+ * Aplica una transformación bidireccional sobre otro esquema.
579
+ *
580
+ * @param schema - Esquema base (tipo wire).
581
+ * @param decode - Función de decodificación (wire → app).
582
+ * @param encode - Función de codificación (app → wire).
583
+ *
584
+ * @example
585
+ * ```ts
586
+ * // wire: centavos (entero), app: dólares (flotante)
587
+ * q.Transform(q.Number(), cents => cents / 100, dollars => dollars * 100)
588
+ * ```
589
+ */
590
+ Transform: <
591
+ A extends QType<any>,
592
+ B
593
+ >(schema: A, decode: (a: Static<A>) => B, encode: (b: B) => Static<A>) => QTransform<A, B>;
594
+ /**
595
+ * Asigna una posición explícita a un campo dentro de un {@link QSchema}.
596
+ *
597
+ * Los campos sin `q.at` reciben posiciones secuenciales automáticamente,
598
+ * saltando las posiciones ya ocupadas por campos explícitos.
599
+ */
600
+ at: <T extends QType<any>>(index: number, schema: T) => QPositioned<T>;
601
+ /**
602
+ * Unión de esquemas. Prueba cada variante en orden.
603
+ *
604
+ * @param variants - Lista de esquemas variantes.
605
+ * @param opts.discriminator - Campo {@link QLiteral} o {@link QEnum} usado
606
+ * para seleccionar la variante correcta con {@link QUnion.match}.
607
+ */
608
+ Union: <T extends QType<any>[]>(variants: [...T], opts?: {
609
+ discriminator?: string;
610
+ }) => QUnion<T>;
611
+ };
612
+ export { q, isPositioned, Static, SchemaProps, SafeResult, QtypeParseError, QUnion, QType, QTuple, QTransform, QString, QSchema, QPositioned, QOptional, QObject, QNumber, QNullable, QLiteral, QInteger, QEnum, QDefault, QDate, QBoolean, QArray, FilterAt, EncodeOptions, DecodeContext };