![](/img/trans.png)
[英]TypeScript use generic function parameter in curry function
[英]Typescript - Conditionally optional generic function parameter
我正在編寫一個庫,在其中生成帶有參數的 sql 條語句。 我希望我可以添加一些 typescript 魔法來實現它,以便在提供空參數列表時,我可以將 function 參數設為可選。 我不確定如何一般地完成此操作。 這是基本類型:
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()
顯然,這個 function 在調用.all
時會期望{}
。 我的下一個想法是可以跳過undefined
的 arg:
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()
我希望這里有人對我如何完成這項工作有想法。 也許我可以使用元組做一些 typescript 魔術? 實際上,構建這個語句要復雜得多,我在這里進行了簡化以說明問題。
你錯過的事情是將extends
包裝成元組,這樣它就不是分布式的:
type Perhaps<T> = [keyof T] extends [never] ? [] : [T];
另外,請注意我現在返回元組而不是T
或T | undefined
T | undefined
。 那是因為現在,我們不是直接給參數一個類型,而是使用Perhaps
作為 function 接受的所有參數的類型(作為 rest 參數):
class Statement<Params> {
exec(...[params]: Perhaps<Params>) { /* do stuff */ }
all(...[params]: Perhaps<Params>) { /* do stuff */ }
one(...[params]: Perhaps<Params>) { /* do stuff */ }
}
當Perhaps
給我們一個空元組時,該方法不接受 arguments。當它給我們[T]
時, params
的類型是T
。
所以現在,當Params
是{}
時,這有效:
const rows = list_stmt.all(); // okay
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.