Skip to content

Instantly share code, notes, and snippets.

@wreulicke
Created September 19, 2017 06:24
Show Gist options
  • Save wreulicke/e45c3eb093acfd489708ffccee15636e to your computer and use it in GitHub Desktop.
Save wreulicke/e45c3eb093acfd489708ffccee15636e to your computer and use it in GitHub Desktop.
TypeSafeなbuilder
type DiffKey<T extends string, U extends string> = (
& {[P in T]: P }
& {[P in U]: never }
& { [x: string]: never }
)[T];
type Omit<T, K extends keyof T> = Pick<T, DiffKey<keyof T, K>>
type Some = {
x: string,
y: string,
z: string
}
type Builder<T, R = T> =
& ({[K in keyof T]: (value: T[K]) => Builder<Omit<T, K>, R>})
& ({ with: <K extends keyof T = keyof T>(value: T) => Builder<Omit<T, K>, R> })
& ({ build: (this: Builder<{[x: string]: never}, R>) => R })
declare var builder: Builder<Some>
builder.x("zzz").y("yyy").z("dddd")
const some:Some = builder.x("vvv")
.with({
y: "ccc",
z:"ddd"
}).build()
const v = builder.x("x").y("y").z("zzz").build();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment