簡體   English   中英

Typescript - 有條件可選的通用 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];

另外,請注意我現在返回元組而不是TT | 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM