TypeScript:如何在方法内部“更改”方法参数的类型?

时间:2019-01-28 10:01:23

标签: typescript function types parameters restriction

我有一个发票,状态可以是“新/已开票”。我有一个doInvoicing方法,该方法需要新发票并返回已开具发票的发票。但是由于发票绑定到新状态,所以我无法更改其状态。

目前,我只能考虑将输入发票转换为“发票”。但是,这在类型检查中留下了一个漏洞,因为它无法验证我是否将发票状态设置为“已开票”。我认为为此所需的操作必须结合强制转换/设置值的步骤(如果可能)。

doInvoicing(invoice: Invoice & { state: invoiceState.New }):
        Invoice & { state: invoiceState.Invoiced } {

    var invoiced = invoice as Invoice & { state: invoiceState.Invoiced }; 
    invoiced.state = invoiceState.Invoiced;    // This MUST happen, but unverified
    return invoiced;
}

enum invoiceState {
    New, Invoiced
}

2 个答案:

答案 0 :(得分:2)

以您设置的方式,我看不到没有创建新的发票对象(或者,当然,使用类型断言或any进行伪造)的方法:

return {...invoice, state: InvoiceState.Invoiced};

请注意,传播仅是浅表复制,在这里看起来就足够了,但是...

答案 1 :(得分:0)

我找到了一种可以避免复制的好的解决方案。用“ setProperty”方法封装更改:

changeProp<V extends T[K], T, K extends keyof T>(obj:
        { [P in keyof T]: T[P] }, key: K, value: V): T & { [P in K]: V } {

    obj[key] = value;   // The required change is not verified, but at least only 1 copy for entire program
    return obj as T & { [P in K]: V };
}

这是一个问题,返回的类型仅在V方面受V类型限制,而在传入的值方面不受限制。尽管如此,它可以用显式的泛型参数声明:

var invoiced: InvoicedInvoice = this.changeProp<invoiceState.Invoiced, Invoice, "state">(invoice, "state", invoiceState.Invoiced);

现在的问题是必须声明所有通用参数,而不仅是V。最好只声明V或不声明任何通用参数。