@@ -394,30 +394,55 @@ type ParseField<Input extends string> = Input extends ''
394
394
* - `field`
395
395
* - `field::type`
396
396
* - `field->json...`
397
- *
398
- * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`.
397
+ * - `field->json...::type`
399
398
*/
400
399
type ParseFieldWithoutEmbeddedResource < Input extends string > = Input extends ''
401
400
? ParserError < 'Empty string' >
402
- : ParseIdentifier < Input > extends [ infer Name , `${infer Remainder } `]
403
- ? ParseJsonAccessor < EatWhitespace < Remainder > > extends [
404
- infer PropertyName ,
405
- infer PropertyType ,
406
- `${infer Remainder } `
407
- ]
408
- ? // `field->json...`
409
- [ { name : PropertyName ; original : PropertyName ; type : PropertyType } , EatWhitespace < Remainder > ]
410
- : EatWhitespace < Remainder > extends `::${infer Remainder } `
411
- ? ParseIdentifier < Remainder > extends [ `${infer CastType } `, `${infer Remainder } `]
412
- ? // `field::type`
413
- CastType extends PostgreSQLTypes
414
- ? [ { name : Name ; type : TypeScriptTypes < CastType > } , EatWhitespace < Remainder > ]
415
- : ParserError < `Invalid type for \`::\` operator \`$ { CastType } \``>
416
- : ParserError < `Invalid type for \`::\` operator at \`$ { Remainder } \``>
401
+ : ParseFieldWithoutEmbeddedResourceAndTypeCast < Input > extends [ infer Field , `${infer Remainder } `]
402
+ ? ParseFieldTypeCast < EatWhitespace < Remainder > > extends [ infer Type , `${infer Remainder } `]
403
+ ? // `field::type`
404
+ [ Field & { type : Type } , EatWhitespace < Remainder > ]
405
+ : ParseFieldTypeCast < EatWhitespace < Remainder > > extends ParserError < string >
406
+ ? ParseFieldTypeCast < EatWhitespace < Remainder > >
417
407
: // `field`
418
- [ { name : Name ; original : Name } , EatWhitespace < Remainder > ]
408
+ [ Field , EatWhitespace < Remainder > ]
419
409
: ParserError < `Expected identifier at \`${Input } \``>
420
410
411
+ /**
412
+ * Parses a field excluding embedded resources or typecasting, without preceding field renaming.
413
+ * This is one of the following:
414
+ * - `field`
415
+ * - `field->json...`
416
+ */
417
+ type ParseFieldWithoutEmbeddedResourceAndTypeCast < Input extends string > =
418
+ ParseIdentifier < Input > extends [ infer Name , `${infer Remainder } `]
419
+ ? ParseJsonAccessor < EatWhitespace < Remainder > > extends [
420
+ infer PropertyName ,
421
+ infer PropertyType ,
422
+ `${infer Remainder } `
423
+ ]
424
+ ? // `field->json...`
425
+ [
426
+ { name : PropertyName ; original : PropertyName ; type : PropertyType } ,
427
+ EatWhitespace < Remainder >
428
+ ]
429
+ : // `field`
430
+ [ { name : Name ; original : Name } , EatWhitespace < Remainder > ]
431
+ : ParserError < `Expected field at \`${Input } \``>
432
+
433
+ /**
434
+ * Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"]
435
+ * or the original string input indicating that no typecast was found.
436
+ */
437
+ type ParseFieldTypeCast < Input extends string > = EatWhitespace < Input > extends `::${infer Remainder } `
438
+ ? ParseIdentifier < EatWhitespace < Remainder > > extends [ `${infer CastType } `, `${infer Remainder } `]
439
+ ? // Ensure that `CastType` is a valid type.
440
+ CastType extends PostgreSQLTypes
441
+ ? [ TypeScriptTypes < CastType > , EatWhitespace < Remainder > ]
442
+ : ParserError < `Invalid type for \`::\` operator \`$ { CastType } \``>
443
+ : ParserError < `Invalid type for \`::\` operator at \`$ { Remainder } \``>
444
+ : Input
445
+
421
446
/**
422
447
* Parses a node.
423
448
* A node is one of the following:
0 commit comments