是否可以使用Typescript做类似的事情:
class DSL {
private sql: string = '';
get book(): IBook {
...
}
get author(): IAuthor {
...
}
get eq(val: string): {
// Add eq to book/author numbers
}
get gt(val: number): {
// Add gt to book/author numbers
}
sql(); // Output the final sql query and return it
}
我最终想写些类似的东西:
new DSL().author.name.eq('bob').and.age.gt(20).sql()
并输出:
SELECT * FROM AUTHORS WHERE name = 'bob' AND age > 20
在键入对象时,我很难为每个对象属性应用方法(等式,gt ...)。
答案 0 :(得分:3)
根据您要编写查询的方式,将对输入内容进行一些编辑。
从您要编写查询的方式开始,我们推断author
应该是与IAuthor
形状相同的对象(即具有所有属性),但是每个属性都应该是一个对象具有适当的可能运算符作为方法,接受比较器值。
从那里我们需要返回一个带有所有可能的布尔运算符的对象,并且该对象的返回类型使我们回到原始状态。
让它适用于所有可能的组合是一项艰巨的任务,因此,SO并不是此论坛,但是适合您的示例并应帮助您入门的东西看起来像这样:
type Fields<T> = {
[P in keyof T] : Operators<T[P], T>
}
type Operators<TValue, TReturn> = {
eq(value: TValue): BoolOperators<TReturn>
gt(value: TValue): BoolOperators<TReturn>
}
type BoolOperators<T> = {
and: Fields<T>,
or : Fields<T>
sql(): string;
}
interface IAuthor {
name: string;
age: number;
}
class DSL {
get author(): Fields<IAuthor> {
return null as any // insert reasonable implementation, since the members of the interface are not known at runtime I would suggest a Proxy approach
}
}
new DSL().author.name.eq('bob').and.age.gt(20).sql() // ok
new DSL().author.name.eq('bob').and.age.gt("20").sql() // error
希望这会有所帮助,如果您陷入细节中,可以随时提出后续问题,但是上面的代码演示了通用方法。