Skip to content

Commit c886460

Browse files
committed
With Type Modifier
1 parent 08600dd commit c886460

3 files changed

Lines changed: 48 additions & 17 deletions

File tree

design/syntax/syntax.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,21 @@ const Base = Runtime.Union([
288288
Runtime.Ref('Reference')
289289
])
290290
// ------------------------------------------------------------------
291+
// With
292+
// ------------------------------------------------------------------
293+
const With = Runtime.Union([
294+
Runtime.Tuple([Runtime.Const('with'), Runtime.Ref('JsonObject')]),
295+
Runtime.Tuple([])
296+
])
297+
// ------------------------------------------------------------------
291298
// Factor
292299
// ------------------------------------------------------------------
293300
const Factor = Runtime.Tuple([
294301
Runtime.Ref('KeyOf'),
295302
Runtime.Ref('Base'),
296303
Runtime.Ref('IndexArray'),
297-
Runtime.Ref('Extends')
304+
Runtime.Ref('Extends'),
305+
Runtime.Ref('With')
298306
])
299307
// ------------------------------------------------------------------
300308
// Expr
@@ -649,7 +657,6 @@ const Options = Runtime.Tuple([
649657
// Options generic type, and thus span multiple parsing contexts
650658
//
651659
// ------------------------------------------------------------------
652-
653660
// ------------------------------------------------------------------
654661
// JsonNumber
655662
// ------------------------------------------------------------------
@@ -953,6 +960,7 @@ export const SyntaxModule = new Runtime.Module({
953960
IndexArray,
954961
Extends,
955962
Base,
963+
With,
956964
Factor,
957965
ExprTermTail,
958966
ExprTerm,

src/type/script/mapping.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,18 @@ export function BaseMapping(input: [unknown, unknown, unknown] | unknown): unkno
542542
: input as T.TSchema
543543
}
544544
// -------------------------------------------------------------------
545-
// Factor: [KeyOf, Base, IndexArray, Extends]
545+
// With: ['with', JsonObject] | []
546+
// -------------------------------------------------------------------
547+
export type TWithMapping<Input extends [unknown, unknown] | []> = (
548+
Input extends ['with', infer Options extends Record<PropertyKey, unknown>]
549+
? Options
550+
: []
551+
)
552+
export function WithMapping(input: [unknown, unknown] | []): unknown {
553+
return Guard.IsEqual(input.length, 2) ? input[1] : []
554+
}
555+
// -------------------------------------------------------------------
556+
// Factor: [KeyOf, Base, IndexArray, Extends, With]
546557
// -------------------------------------------------------------------
547558
type TFactorIndexArray<Type extends T.TSchema, IndexArray extends unknown[]> = (
548559
IndexArray extends [infer Left extends T.TSchema[], ...infer Right extends unknown[]] ? (
@@ -556,16 +567,21 @@ type TFactorExtends<Type extends T.TSchema, Extends extends unknown[]> = (
556567
? C.TConditionalDeferred<Type, Right, True, False>
557568
: Type
558569
)
559-
export type TFactorMapping<Input extends [unknown, unknown, unknown, unknown]> = (
560-
Input extends [infer KeyOf extends boolean, infer Type extends T.TSchema, infer IndexArray extends unknown[], infer Extend extends unknown[]]
561-
? KeyOf extends true
562-
? TFactorExtends<C.TKeyOfDeferred<TFactorIndexArray<Type, IndexArray>>, Extend>
563-
: TFactorExtends<TFactorIndexArray<Type, IndexArray>, Extend>
570+
type TFactorWith<Type extends T.TSchema, With extends unknown> = (
571+
With extends Record<PropertyKey, unknown>
572+
? C.TOptionsDeferred<Type, With>
573+
: Type
574+
)
575+
export type TFactorMapping<Input extends [unknown, unknown, unknown, unknown, unknown]> = (
576+
Input extends [infer KeyOf extends boolean, infer Type extends T.TSchema, infer IndexArray extends unknown[], infer Extend extends unknown[], infer WithClause extends unknown]
577+
? TFactorWith<KeyOf extends true
578+
? TFactorExtends<C.TKeyOfDeferred<TFactorIndexArray<Type, IndexArray>>, Extend>
579+
: TFactorExtends<TFactorIndexArray<Type, IndexArray>, Extend>
580+
, WithClause>
564581
: never
565582
)
566583
// deno-coverage-ignore-start
567-
// ...
568-
const FactorIndexArray = (Type: T.TSchema, indexArray: unknown[]): T.TSchema => {
584+
function FactorIndexArray(Type: T.TSchema, indexArray: unknown[]): T.TSchema {
569585
return indexArray.reduce<T.TSchema>((result, left) => {
570586
const _left = left as T.TSchema[]
571587
return (
@@ -576,16 +592,21 @@ const FactorIndexArray = (Type: T.TSchema, indexArray: unknown[]): T.TSchema =>
576592
}, Type)
577593
}
578594
// deno-coverage-ignore-stop
579-
const FactorExtends = (type: T.TSchema, extend: T.TSchema[]) => {
595+
function FactorExtends(type: T.TSchema, extend: T.TSchema[]): T.TSchema {
580596
return Guard.IsEqual(extend.length, 3)
581597
? C.ConditionalDeferred(type, extend[0], extend[1], extend[2])
582598
: type
583599
}
584-
export function FactorMapping(input: [unknown, unknown, unknown, unknown]): unknown {
585-
const [keyOf, type, indexArray, extend] = input as [boolean, T.TSchema, unknown[], T.TSchema[]]
586-
return keyOf
600+
function FactorWith(type: T.TSchema, withClause: unknown): T.TSchema {
601+
return Guard.IsArray(withClause) && Guard.IsEqual(withClause.length, 0)
602+
? type
603+
: C.OptionsDeferred(type, withClause as T.TSchema)
604+
}
605+
export function FactorMapping(input: [unknown, unknown, unknown, unknown, unknown]): unknown {
606+
const [keyOf, type, indexArray, extend, withClause] = input as [boolean, T.TSchema, unknown[], T.TSchema[], unknown]
607+
return FactorWith(keyOf
587608
? FactorExtends(C.KeyOfDeferred(FactorIndexArray(type, indexArray)), extend)
588-
: FactorExtends(FactorIndexArray(type, indexArray), extend)
609+
: FactorExtends(FactorIndexArray(type, indexArray), extend), withClause)
589610
}
590611
// ------------------------------------------------------------------
591612
//

src/type/script/parser.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ export type TIndexArray_0<Input extends string, Result extends unknown[] = []> =
7676
export type TIndexArray<Input extends string> = TIndexArray_0<Input> extends [infer _0 extends ([unknown, unknown, unknown] | [unknown, unknown])[], infer Input extends string] ? [S.TIndexArrayMapping<_0>, Input] : []
7777
export type TExtends<Input extends string> = ((Token.TConst<'extends', Input> extends [infer _0, infer Input extends string] ? (TType<Input> extends [infer _1, infer Input extends string] ? (Token.TConst<'?', Input> extends [infer _2, infer Input extends string] ? (TType<Input> extends [infer _3, infer Input extends string] ? (Token.TConst<':', Input> extends [infer _4, infer Input extends string] ? (TType<Input> extends [infer _5, infer Input extends string] ? [[_0, _1, _2, _3, _4, _5], Input] : []) : []) : []) : []) : []) : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : []) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown, unknown] | [], infer Input extends string] ? [S.TExtendsMapping<_0>, Input] : []
7878
export type TBase<Input extends string> = ((Token.TConst<'(', Input> extends [infer _0, infer Input extends string] ? (TType<Input> extends [infer _1, infer Input extends string] ? (Token.TConst<')', Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : []) : []) : []) extends [infer _0, infer Input extends string] ? [_0, Input] : TKeyword<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : T_Object_<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TTuple<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TTemplateLiteral<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TLiteral<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TConstructor<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : T_Function_<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TMapped<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TOptions<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TGenericCall<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : TReference<Input> extends [infer _0, infer Input extends string] ? [_0, Input] : []) extends [infer _0 extends [unknown, unknown, unknown] | unknown, infer Input extends string] ? [S.TBaseMapping<_0>, Input] : []
79-
export type TFactor<Input extends string> = (TKeyOf<Input> extends [infer _0, infer Input extends string] ? (TBase<Input> extends [infer _1, infer Input extends string] ? (TIndexArray<Input> extends [infer _2, infer Input extends string] ? (TExtends<Input> extends [infer _3, infer Input extends string] ? [[_0, _1, _2, _3], Input] : []) : []) : []) : []) extends [infer _0 extends [unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TFactorMapping<_0>, Input] : []
79+
export type TWith<Input extends string> = ((Token.TConst<'with', Input> extends [infer _0, infer Input extends string] ? (TJsonObject<Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : []) extends [infer _0 extends [unknown, unknown] | [], infer Input extends string] ? [S.TWithMapping<_0>, Input] : []
80+
export type TFactor<Input extends string> = (TKeyOf<Input> extends [infer _0, infer Input extends string] ? (TBase<Input> extends [infer _1, infer Input extends string] ? (TIndexArray<Input> extends [infer _2, infer Input extends string] ? (TExtends<Input> extends [infer _3, infer Input extends string] ? (TWith<Input> extends [infer _4, infer Input extends string] ? [[_0, _1, _2, _3, _4], Input] : []) : []) : []) : []) : []) extends [infer _0 extends [unknown, unknown, unknown, unknown, unknown], infer Input extends string] ? [S.TFactorMapping<_0>, Input] : []
8081
export type TExprTermTail<Input extends string> = ((Token.TConst<'&', Input> extends [infer _0, infer Input extends string] ? (TFactor<Input> extends [infer _1, infer Input extends string] ? (TExprTermTail<Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : []) : []) : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : []) extends [infer _0 extends [unknown, unknown, unknown] | [], infer Input extends string] ? [S.TExprTermTailMapping<_0>, Input] : []
8182
export type TExprTerm<Input extends string> = (TFactor<Input> extends [infer _0, infer Input extends string] ? (TExprTermTail<Input> extends [infer _1, infer Input extends string] ? [[_0, _1], Input] : []) : []) extends [infer _0 extends [unknown, unknown], infer Input extends string] ? [S.TExprTermMapping<_0>, Input] : []
8283
export type TExprTail<Input extends string> = ((Token.TConst<'|', Input> extends [infer _0, infer Input extends string] ? (TExprTerm<Input> extends [infer _1, infer Input extends string] ? (TExprTail<Input> extends [infer _2, infer Input extends string] ? [[_0, _1, _2], Input] : []) : []) : []) extends [infer _0, infer Input extends string] ? [_0, Input] : [[], Input] extends [infer _0, infer Input extends string] ? [_0, Input] : []) extends [infer _0 extends [unknown, unknown, unknown] | [], infer Input extends string] ? [S.TExprTailMapping<_0>, Input] : []
@@ -207,7 +208,8 @@ export const IndexArray_0 = (input: string, result: unknown[] = []): [unknown[],
207208
export const IndexArray = (input: string): [unknown, string] | [] => If(IndexArray_0(input), ([_0, input]) => [S.IndexArrayMapping(_0 as ([unknown, unknown, unknown] | [unknown, unknown])[]), input])
208209
export const Extends = (input: string): [unknown, string] | [] => If(If(If(Token.Const('extends', input), ([_0, input]) => If(Type(input), ([_1, input]) => If(Token.Const('?', input), ([_2, input]) => If(Type(input), ([_3, input]) => If(Token.Const(':', input), ([_4, input]) => If(Type(input), ([_5, input]) => [[_0, _1, _2, _3, _4, _5], input])))))), ([_0, input]) => [_0, input], () => If([[], input], ([_0, input]) => [_0, input], () => [])), ([_0, input]) => [S.ExtendsMapping(_0 as [unknown, unknown, unknown, unknown, unknown, unknown] | []), input])
209210
export const Base = (input: string): [unknown, string] | [] => If(If(If(Token.Const('(', input), ([_0, input]) => If(Type(input), ([_1, input]) => If(Token.Const(')', input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If(Keyword(input), ([_0, input]) => [_0, input], () => If(_Object_(input), ([_0, input]) => [_0, input], () => If(Tuple(input), ([_0, input]) => [_0, input], () => If(TemplateLiteral(input), ([_0, input]) => [_0, input], () => If(Literal(input), ([_0, input]) => [_0, input], () => If(Constructor(input), ([_0, input]) => [_0, input], () => If(_Function_(input), ([_0, input]) => [_0, input], () => If(Mapped(input), ([_0, input]) => [_0, input], () => If(Options(input), ([_0, input]) => [_0, input], () => If(GenericCall(input), ([_0, input]) => [_0, input], () => If(Reference(input), ([_0, input]) => [_0, input], () => [])))))))))))), ([_0, input]) => [S.BaseMapping(_0 as [unknown, unknown, unknown] | unknown), input])
210-
export const Factor = (input: string): [unknown, string] | [] => If(If(KeyOf(input), ([_0, input]) => If(Base(input), ([_1, input]) => If(IndexArray(input), ([_2, input]) => If(Extends(input), ([_3, input]) => [[_0, _1, _2, _3], input])))), ([_0, input]) => [S.FactorMapping(_0 as [unknown, unknown, unknown, unknown]), input])
211+
export const With = (input: string): [unknown, string] | [] => If(If(If(Token.Const('with', input), ([_0, input]) => If(JsonObject(input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [_0, input], () => If([[], input], ([_0, input]) => [_0, input], () => [])), ([_0, input]) => [S.WithMapping(_0 as [unknown, unknown] | []), input])
212+
export const Factor = (input: string): [unknown, string] | [] => If(If(KeyOf(input), ([_0, input]) => If(Base(input), ([_1, input]) => If(IndexArray(input), ([_2, input]) => If(Extends(input), ([_3, input]) => If(With(input), ([_4, input]) => [[_0, _1, _2, _3, _4], input]))))), ([_0, input]) => [S.FactorMapping(_0 as [unknown, unknown, unknown, unknown, unknown]), input])
211213
export const ExprTermTail = (input: string): [unknown, string] | [] => If(If(If(Token.Const('&', input), ([_0, input]) => If(Factor(input), ([_1, input]) => If(ExprTermTail(input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If([[], input], ([_0, input]) => [_0, input], () => [])), ([_0, input]) => [S.ExprTermTailMapping(_0 as [unknown, unknown, unknown] | []), input])
212214
export const ExprTerm = (input: string): [unknown, string] | [] => If(If(Factor(input), ([_0, input]) => If(ExprTermTail(input), ([_1, input]) => [[_0, _1], input])), ([_0, input]) => [S.ExprTermMapping(_0 as [unknown, unknown]), input])
213215
export const ExprTail = (input: string): [unknown, string] | [] => If(If(If(Token.Const('|', input), ([_0, input]) => If(ExprTerm(input), ([_1, input]) => If(ExprTail(input), ([_2, input]) => [[_0, _1, _2], input]))), ([_0, input]) => [_0, input], () => If([[], input], ([_0, input]) => [_0, input], () => [])), ([_0, input]) => [S.ExprTailMapping(_0 as [unknown, unknown, unknown] | []), input])

0 commit comments

Comments
 (0)