@@ -394,30 +394,55 @@ type ParseField<Input extends string> = Input extends ''
394394 * - `field`
395395 * - `field::type`
396396 * - `field->json...`
397- *
398- * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`.
397+ * - `field->json...::type`
399398 */
400399type ParseFieldWithoutEmbeddedResource < Input extends string > = Input extends ''
401400 ? 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 > >
417407 : // `field`
418- [ { name : Name ; original : Name } , EatWhitespace < Remainder > ]
408+ [ Field , EatWhitespace < Remainder > ]
419409 : ParserError < `Expected identifier at \`${Input } \``>
420410
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+
421446/**
422447 * Parses a node.
423448 * A node is one of the following:
0 commit comments