Created
August 5, 2024 02:00
-
-
Save AlexJWayne/a3d53d06baed48d4ac227d975312ce80 to your computer and use it in GitHub Desktop.
This file contains 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
// exported types will be available for you to import from compiled files | |
// to distinguish between objects ({}) and blocks, blocks have a colon before the opening brace (:{}) | |
export type parseRoute = (route: string) => :{ | |
// assign computations to variables like this | |
let parts = route.split("/"); // -> ["users", "<id:string>", "posts", "<index:number>"] | |
// last expression is the return value, like in Rust | |
parts | |
// method chaining! | |
.filter((part) => part.startsWith("<")) // -> ["<id:string>", "<index:number>"] | |
.map((part) => match part { | |
// infer subparts of the expression during pattern matching | |
`<${infer name}:${infer ty}>` -> [name, ty] | |
}) // -> [["id", "string"], ["index", "number"]] | |
.toUnion() // -> ["id", "string"] | ["index", "number"] | |
.fromEntries() // -> { id: "string"; index: "number" } | |
.mapValues((ty) => match ty { | |
"string" -> string, | |
"number" -> number | |
}) // -> { id: string; index: number } | |
} | |
type params = parseRoute("/users/<id:string>/posts/<index:number>") | |
// ^? | |
// { id: string; index: number; } | |
// Add tests alongside your code | |
#[test] :{ | |
AssertEqual( | |
parseRoute("/users/<id:string>/posts/<index:number>"), | |
{ id: string, index: number } | |
) | |
AssertEqual( | |
parseRoute("/users/noParams"), | |
{} | |
) | |
} |
This file contains 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
import { | |
type Call, | |
type Fn, | |
type PartialApply, | |
type Apply, | |
type arg, | |
type Booleans, | |
} from "tartak/hot"; | |
import { | |
type Split, | |
type StartsWith, | |
type Filter, | |
type Map, | |
type ToUnion, | |
type FromEntries, | |
type MapValues, | |
type Expect, | |
} from "tartak/prelude"; | |
interface lambda_temp_1 extends Fn { | |
return: StartsWith<this["arg1"], "<">; | |
} | |
interface lambda_temp_2 extends Fn { | |
return: this["arg1"] extends `<${infer name}:${infer ty}>` | |
? [name, ty] | |
: undefined; | |
} | |
interface lambda_temp_3 extends Fn { | |
return: this["arg1"] extends "string" | |
? string | |
: this["arg1"] extends "number" | |
? number | |
: undefined; | |
} | |
interface lambda_temp_4 extends Fn { | |
return: Split<this["arg1"], "/"> extends infer parts extends Split< | |
this["arg1"], | |
"/" | |
> | |
? MapValues< | |
FromEntries< | |
ToUnion< | |
Map< | |
Filter< | |
parts, | |
[parts, this["arg1"]] extends infer scope | |
? PartialApply<lambda_temp_1, [scope]> | |
: never | |
>, | |
[parts, this["arg1"]] extends infer scope | |
? PartialApply<lambda_temp_2, [scope]> | |
: never | |
> | |
> | |
>, | |
[parts, this["arg1"]] extends infer scope | |
? PartialApply<lambda_temp_3, [scope]> | |
: never | |
> | |
: never; | |
} | |
export type parseRouteHOT = PartialApply<lambda_temp_4, [[]]>; | |
export type parseRoute<route extends string> = Call<parseRouteHOT, route>; | |
type params = | |
"/users/<id:string>/posts/<index:number>" extends infer temp_5 extends "/users/<id:string>/posts/<index:number>" | |
? ( | |
temp_5 extends any ? Apply<parseRouteHOT, [temp_5]> : never | |
) extends never | |
? PartialApply<parseRouteHOT, [temp_5]> | |
: Apply<parseRouteHOT, [temp_5]> | |
: never; | |
// test | |
namespace test { | |
type temp_7 = Expect< | |
Call< | |
Booleans.Equals< | |
"/users/<id:string>/posts/<index:number>" extends infer temp_6 extends "/users/<id:string>/posts/<index:number>" | |
? ( | |
temp_6 extends any ? Apply<parseRouteHOT, [temp_6]> : never | |
) extends never | |
? PartialApply<parseRouteHOT, [temp_6]> | |
: Apply<parseRouteHOT, [temp_6]> | |
: never, | |
{ id: string; index: number } | |
> | |
> | |
>; | |
type temp_9 = Expect< | |
Call< | |
Booleans.Equals< | |
"/users/noParams" extends infer temp_8 extends "/users/noParams" | |
? ( | |
temp_8 extends any ? Apply<parseRouteHOT, [temp_8]> : never | |
) extends never | |
? PartialApply<parseRouteHOT, [temp_8]> | |
: Apply<parseRouteHOT, [temp_8]> | |
: never, | |
{} | |
> | |
> | |
>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment