Skip to content

Instantly share code, notes, and snippets.

@keigoi
Last active November 5, 2020 06:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keigoi/44c679a778c5c3f5fa0c037631619bfb to your computer and use it in GitHub Desktop.
Save keigoi/44c679a778c5c3f5fa0c037631619bfb to your computer and use it in GitHub Desktop.
type Global = {[L:string]:Local}
type Local = {kind:string; role:string, bra:{[L:string]:Local}}
type Keys<T extends {[L:string]:{}}> = T extends infer U ? keyof U : never;
type Assoc<T extends {[L:string]:{}}, K extends string> = T extends unknown ? K extends keyof T ? T[K] : never : never;
type Force<T extends Local> =
[T] extends [Local]
? {kind:T["kind"], role:T["role"], bra:{[X in Keys<T["bra"]>]: Force<Assoc<T["bra"], X>>}}
: never
type Comm<R1 extends XS, R2 extends XS, XS extends string, T extends {[L:string]:Global}> =
{[X in XS] :
X extends R1
? {kind:"send", role:R2, bra:{[L in keyof T]:T[L][X]}}
: X extends R2
? {kind:"recv", role:R1, bra:{[L in keyof T]:T[L][X]}}
: T[keyof T][X]
}
type Finish<XS extends string> = {[X in XS]: {kind:"close", bra:{}}}
type abc = "a"|"b"|"c"
type U1 = Comm<"a", "b", abc,
{l0:Comm<"b", "c", abc, {l2:Comm<"c", "a", abc, {l3:U1}>}>,
l1:Comm<"b", "c", abc, {l4:Comm<"c", "a", abc, {l3:U1}>}>}>
type Ua = Force<U1["a"]>
type Ub = Force<U1["b"]>
type Uc = Force<U1["c"]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment