Created
June 14, 2018 08:00
-
-
Save mattiamanzati/e66c728fd25e3ee776fae7cc091a7c50 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type True = 'true' | |
type False = 'false' | |
type Bool = True | False | |
type If<B extends Bool, IfTrue, IfFalse> = { | |
true: IfTrue | |
false: IfFalse | |
}[B] | |
type Not<B extends Bool> = If<B, False, True> | |
type And<B1 extends Bool, B2 extends Bool> = If<B1, B2, False> | |
type Test<IfAtMilano extends Bool, IfIsDrunk extends Bool> = | |
If<And<IfAtMilano, IfIsDrunk>, | |
"Ciao MilanoTS! Bella Festa!", | |
"Dove sono?"> | |
type Run = Test<True, False> | |
type Zero = { | |
isZero: True | |
prevNat: never | |
} | |
type Succ<N extends Nat> = { | |
isZero: False, | |
prevNat: N | |
} | |
type Nat = Zero | Succ<any> | |
type One = Succ<Zero> | |
type Two = Succ<One> | |
type IsZero<N extends Nat> = N["isZero"] | |
type Prev<N extends Nat> = N["prevNat"] | |
/** | |
* for(let i = 10; i != 0; i--) | |
*/ | |
type ForLoop<N extends Nat> = If<IsZero<N>, "Batman!", {NaNa: ForLoop<Prev<N>>}> | |
/** | |
* while(i != 0){ | |
* if(i = 0){ | |
* v = "Batman!" | |
* }else{ | |
* v = {NaNa: v} | |
* } | |
* } | |
*/ | |
type Test2 = ForLoop<Succ<Succ<Succ<Succ<Succ<Succ<Succ<Zero>>>>>>>> | |
type AddNat<N1 extends Nat, N2 extends Nat> = { | |
true: N2 | |
false: Succ<AddNat<Prev<N1>, N2>> | |
}[IsZero<N1>] | |
// 1 + 10 | |
// (0 + 10) + 1 | |
type Four = AddNat<Two, Two> | |
declare const a: Test2 | |
a.NaNa.NaNa.NaNa.NaNa.NaNa.NaNa.NaNa | |
type HListEmpty = { | |
isEmpty: True | |
item: never | |
nextList: never | |
} | |
type HListNextItem<V, L extends HList> = { | |
isEmpty: False | |
item: V | |
nextList: L | |
} | |
type HList = HListEmpty | HListNextItem<any, any> | |
type HListIsEmpty<L extends HList> = L["isEmpty"] | |
type HListItem<L extends HList> = L["item"] | |
type HListNextList<L extends HList> = L["nextList"] | |
type HListConcat<L1 extends HList, L2 extends HList> = { | |
true: L2, | |
false: HListNextItem<HListItem<L1>, HListConcat<HListNextList<L1>, L2>> | |
}[HListIsEmpty<L1>] | |
type TestList = HListNextItem<"Primo", HListNextItem<"due", HListNextItem<"lol", HListEmpty>>> | |
type Test3<L extends HList> = { | |
true: True, | |
false: {[K in L["item"]]: Test3<L["nextList"]>} | |
}[L["isEmpty"]] | |
type RunProg = Test3<TestList> | |
declare const ab: RunProg | |
ab.Primo.due.lol // => 'true' | |
type RouteLiteral<N extends string> = string | |
type RouteCapture<N extends string> = { name: N} | |
type RouteSegment = RouteLiteral<string> | RouteCapture<string> | |
type Route = HList | |
type RouteBuilder<R extends Route> = { | |
route: R | |
addLiteral<N extends string>(literal: N): RouteBuilder<HListConcat<R, HListNextItem<RouteLiteral<N>, HListEmpty>>> | |
addCapture<N extends string>(literal: N): RouteBuilder<HListConcat<R, HListNextItem<RouteCapture<N>, HListEmpty>>> | |
} | |
type RouteToCapture<R extends Route, P = {}> = { | |
true: P | |
false: RouteToCapture<HListNextList<R>, P & (HListItem<R> extends RouteCapture<string> ? {[K in HListItem<R>["name"]]: string} : P)> | |
}[HListIsEmpty<R>] | |
type RouteToRequest<R extends Route> = { | |
input: RouteToCapture<R> | |
} | |
type App<RM extends {[K: string]: Route}> = { | |
routes: RM | |
addRoute<N extends string, R extends Route>(name: N, fn: (rb: RouteBuilder<HListEmpty>) => RouteBuilder<R>): App<RM & {[K in N]: R}> | |
addHandler<N extends keyof RM>(name: N, handler: (request: RouteToRequest<RM[N]>) => string): App<RM> | |
} | |
declare const app: App<{}> | |
const myApp = app | |
.addRoute("postsIndex", url => url | |
.addLiteral("posts") | |
.addLiteral("index")) | |
.addRoute("postView", url => url | |
.addLiteral("posts") | |
.addCapture("post_id") | |
.addCapture("access_token") | |
.addLiteral("view")) | |
.addHandler("postsIndex", req => req.input.post_id) | |
.addHandler("postView", req => req.input.post_id) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment