我正在写一个库,在其中生成带参数的sql语句。我希望我可以添加一些typescript魔术,以便当提供空的参数列表时,我可以使该函数参数可选。我不知道如何一般性地实现这一点。下面是基本类型:
class Statement<Params> {
exec(params: Params) { /* do stuff */ }
all(params: Params) { /* do stuff */ }
one(params: Params) { /* do stuff */ }
}
const create_stmt = new Statement<{ username: string; password: string }>()
create_stmt.exec({ username: 'bob', password: 'secret' })
const list_stmt = new Statement<{}>()
// What I want is to skip this argument since I know its just an empty object. As expected though, there is a type error: "An argument for 'params' was not provided."
const rows = list_stmt.all()
很明显,这个函数在调用.all
时需要{}
。我的下一个想法是可以跳过undefined
参数:
type OptionalOnEmpty<T> = keyof T extends never ? T | undefined : T
class Statement<Params> {
exec(params: OptionalOnEmpty<Params>) { /* do stuff */ }
all(params: OptionalOnEmpty<Params>) { /* do stuff */ }
one(params: OptionalOnEmpty<Params>) { /* do stuff */ }
}
const create_stmt = new Statement<{ username: string; password: string }>()
create_stmt.exec({ username: 'bob', password: 'secret' })
const list_stmt = new Statement<{}>()
// this still fails, I have to at the very least, pass list_stmt.all(undefined)
const rows = list_stmt.all()
我希望这里有人能告诉我如何才能使这个工作。也许有一些打字脚本魔术,我可以做使用元组?在现实中,建立这个语句是更复杂的,我简化了这里显示的问题。
1条答案
按热度按时间ctehm74n1#
您忽略了将
extends
Package 成元组以使其不是分配的:另外,请注意,我现在返回的是元组而不是
T
或T | undefined
。这是因为,现在我们将使用Perhaps
作为函数接受的所有参数的类型(作为rest参数),而不是直接为参数指定类型:当
Perhaps
给我们一个空元组时,该方法不接受任何参数;当它给我们[T]
时,params
的类型是T
。现在,当
Params
为{}
时,可以这样做:Playground