Skip to content

TypeCake is a language that compiles to TypeScript types. (WIP)

License

Notifications You must be signed in to change notification settings

g-plane/TypeCake

Repository files navigation

🍰 TypeCake

TypeCake is a language that compiles to TypeScript types.

Still in progress.

Examples

You can open playground to edit and compile the code on-the-fly.

Declaring "type" function

Playground

fn F1() = X; // semicolon is optional

fn F2(T) = T

fn F3(T: string) = T

fn F4(T = string) = T

fn F5(T: string = string) = T

compiles to TypeScript:

type F1 = X;

type F2<T> = T;

type F3<T extends string> = T;

type F4<T = string> = T;

type F5<T extends string = string> = T;

Declaring object type

Playground

fn Data() = { a: string, b?: number, [x: string]: unknown }

compiles to TypeScript:

type Data = {
  a: string,
  b?: number,
  [x: string]: unknown
};

If expression

Playground

fn F1() = if 's' : string {
  'a'
} else {
  'b'
}

fn F2(T) = if T : string {
  'a'
} else if T : boolean {
  'b'
} else {
  'c'
}

compiles to TypeScript:

type F1 = 's' extends string ? 'a' : 'b';

type F2<T> = T extends string ? 'a' : T extends boolean ? 'b' : 'c';

Switch expression (pattern matching)

Playground

fn F1(T) = switch T {
  string -> 'a',
  boolean -> 'b',
  _ -> 'c',
}

fn F2(T: unknown[]) = switch T {
  [] -> unknown,
  [&First] -> First,
  [any, &Second] -> Second,
  _ -> never,
}

compiles to TypeScript:

type F1<T> = T extends string ? 'a' : T extends boolean ? 'b' : 'c';

type F2<T extends unknown[]> = T extends [] ? unknown : T extends [infer First] ? First : T extends [any, infer Second] ? Second : never;

For expression

Playground

fn F2() = for K in 'click' | 'change' as `on${Capitalize(K)}` {
  K
}

compiles to TypeScript:

type F2 = { [K in 'click' | 'change' as `on${Capitalize<K>}`]: K };

Const-In expression

Playground

fn F(T) =
  const T1 = MyType(1),
        T2 = MyType(2)
  in if T1 : T2 {
    [T1]
  } else {
    [T2]
  }

compiles to TypeScript:

type F<T> = MyType<1> extends infer T1 ? MyType<2> extends infer T2 ? T1 extends T2 ? [T1] : [T2] : never : never;

Pipeline Expression

Playground

fn F() = number
  |> Promise
  |> Set
  |> Record(string)

compiles to TypeScript:

type F = Record<string, Set<Promise<number>>>;

Macro

Experimental. Not implemented yet.

fn F() = union!(string, number)

Import declaration

Playground

from 'a' import a
from 'b' import * as b
from 'c' import { x, y as z }
from 'd' import d, { m, n }

compiles to TypeScript:

import a from 'a';
import * as b from 'b';
import { x, y as z } from 'c';
import d, { m, n } from 'd';

License

MIT License

2021-present (c) Pig Fang