const wit = [
"record user { name: string, age: u32 }",
"variant api-error { not-found, unauthorized(string) }",
"get-user: func(id: u64) -> user;",
"create-post: func(author: user, post: post) -> result<post, api-error>;",
] as const;
type Client = WitClient<ParseWit<typeof wit>>;
// Client["get-user"]: (id: bigint) => Promise<{ name: string; age: number }>
// Client["create-post"]: (author: ...) => Promise<["ok", {...}] | ["err", ["not-found"] | ["unauthorized", string]]>
Why did I do this? Good question. I originally did this work as part of this project: https://sdk.kontor.network/. Kontor is a new Bitcoin metaprotocol that uses WITs to define smart contract interfaces.I carved wit-ts out of the project and removed some domain specific stuff from it, refactored some internals, and extended it to be compatible with a broader subset of the wit specification. Technically there are some valid wit types that would not be handled cleanly here ( e.g. recursive types ).
Tremendous debt is owed to the https://github.com/wevm/abitype project, which does the same thing for Ethereum ABIs and was the direct inspiration for the type-level approach.