jsigbiz / spec

JavaScript signature notation
131 stars 6 forks source link

Recursive or inductive types #15

Open Raynos opened 10 years ago

Raynos commented 10 years ago

I wanted to define EventEmitter<T> somehow and realized I would need induction or recursion to define it.

type HistoryState := { url: String, title: String, data: Any }

type Router := EventEmitter<{
    "route": (HistoryState) => void
}> & {
    (state?: HistoryState) => void,
    addRoute: (
        pattern: String | RegExp,
        handler: (uri: String, {
            splats: Array,
            params: Object,
            data: Any,
            title: String
        }) => void
    ) => void,
    getState: () => HistoryState,
    pushState: (HistoryState) => void,
    replaceState: (HistoryState) => void
    (* methods go, get *)
}

html5-router := EventEmitter<{
    "popstate": (HistoryState) => void
}> & {
    (opts?: {
        html4?: Boolean,
        getState?: () => HistoryState,
        pushState?: (HistoryState) => void,
        replaceState?: (HistoryState) => void
        (* options? *)
    }) => Router
}
(* Introducing inductive types *)
type EventEmitter<{
  key1: (value1) => void,
  key2: (value2) => void,
  ...,
  keyN: (valueN) => void
}> := {
  on: (key1, (value1) => void) => void |
    (key2, (value2) => void) => void |
    ... |
    (keyN, (valueN) => void) => void,
  emit: (key1, value1) => void |
    (key2, value2) => void |
    ...
    (keyN, valueN) => void
}