根据参数

时间:2018-04-05 14:33:45

标签: typescript typescript2.8

在以下情况中,是否可以正确地将result的类型正确推断为boolean

interface ActionWithPayload<T extends string, K> { type: T, payload: K }

function ofType<T extends ActionWithPayload<string, any>>(...param: T["type"][]): T extends ActionWithPayload<typeof param[number], infer U> ? U : never {
    return null;
}

enum one {
    foo = "foo",
    bar = "bar"
}

type action = ActionWithPayload<one.foo, boolean> | ActionWithPayload<one.bar, string>;

var result = ofType<action>(one.foo); // type of result should be boolean

Playground link

1 个答案:

答案 0 :(得分:1)

问题在于T["type"] T actionone.foo | one.barfunction ofType<T extends ActionWithPayload<string, any>, K extends one = one>(...param:K[]): T extends ActionWithPayload<K, infer U> ? U : never { return null as any; } var result = ofType<action, one.foo>(one.foo); // will be boolean ,无论您传递的参数是什么。您需要一个额外的泛型参数,以便编译器推断您传入的枚举成员的文字类型:

one.foo

缺点是您必须显式指定文字类型function ofType<T extends ActionWithPayload<string, any>>() { return function <K extends one = one>(...param:K[]) : T extends ActionWithPayload<K, infer U> ? U : never{ return null; } } var result = ofType<action>()(one.foo); // will be boolean ,因为您不能只指定其中一个类型参数。作为替代方案,您可以使用双函数方法,因此您可以为第一个函数指定类型参数,并让推理适用于第二个函数:

public class Taxes
{
    public int DocumentType { get; set; }

    private XElement BuildBodyXML()
    {
        // other stuff

        Address billAddrObj = GetBillTo(dt);
        Address buyerAddrObj = GetBuyerPrimary(dt);

        var xBillTo = BuildAddress(billAddrObj, "BILL_TO");
        var xBuyer = BuildAddress(buyerAddrObj, "BUYER_PRIMARY");

        var INVOICE = from row in dt.AsEnumerable()
            select new XElement(tcr + "INVOICE", 
            xBillTo, // This one needs to be conditionally included based on DocumentType
            xBuyer, 
            // ... other elements ...
            new XElement(tcr + "INVOICE_NUMBER", row.Field<string>("DOCNUMBR").Trim()));

        // other stuff 

        return INVOICE;
    }

    public XElement BuildAddress(Address anAddress, string Name)
    {
        var xAddress = new XElement(tcr + Name);

        // other stuff 

        return xAddress;
    }
}