Skip to content

Instantly share code, notes, and snippets.

@wernerdegroot
Last active February 22, 2019 18:08
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 wernerdegroot/5146d906e9625cca1049050694281b25 to your computer and use it in GitHub Desktop.
Save wernerdegroot/5146d906e9625cca1049050694281b25 to your computer and use it in GitHub Desktop.
QueryBeak
type Condition<O> = (o: O) => boolean
type QueryableProperty<Alias extends string, Subject, Property> = {
eq(other: Property): Condition<{ [K in Alias]: Subject }>
eq<OtherAlias extends string, OtherSubject>(other: QueryableProperty<OtherAlias, OtherSubject, Property>): Condition<{ [K in Alias]: Subject } & { [K in OtherAlias]: OtherSubject }>
}
type Queryable<Alias extends string, Subject> = { [KS in keyof Subject]: QueryableProperty<Alias, Subject, Subject[KS]> }
type Query<O> = {
where(condition: Condition<O>): Query<O>
join<OtherAlias extends string, OtherSubject>(other: Queryable<OtherAlias, OtherSubject>): Query<O & {[K in OtherAlias]: OtherSubject}>
}
type Person = {
id: string
address: string
name: string
age: number
}
type Address = {
id: string
street: string
}
declare const person: Queryable<'person', Person>
declare const address: Queryable<'address', Address>
declare function select<Alias extends string, Subject>(queryable: Queryable<Alias, Subject>): Query<{ [K in Alias]: Subject }>
select(person).where(person.age.eq(4), trivial()).where(address.street.eq("")).where(person.id.eq(""))
select(person)
.join(address)
.where(person.age.eq(4))
.where(person.address.eq(address.id))
.where(person.id.eq(""))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment