基于字符串参数的Typescript条件返回类型

时间:2019-03-08 08:36:42

标签: typescript generics

使用字符串文字的并集作为输入参数时,删除强制类型转换并将类型放入函数标题中会如何

const get = <T extends "barcode" | "mqtt">(s: T) =>
    s === "barcode" ?
        <T extends "barcode" ? {scan: () => string} : {pan: () => string}>{scan: () => "we are scanning"} :
        <T extends "barcode" ? {scan: () => string} : {pan: () => string}>{pan: () => "we are panning"}

get("barcode").scan() // OK
get("mqtt").pan()     // OK
get("barcode").pan() // Error

我遇到了这个问题,试图回答别人的问题:https://stackoverflow.com/a/55059318/2684980

1 个答案:

答案 0 :(得分:1)

最干净的解决方案是使用重载代替这种情况(尽管没有比类型断言更安全的类型)。您可以在公共签名中使用条件类型,并在实现签名中使用简单的联合。您将需要切换到函数声明,因为函数表达式(箭头或正则表达式)不容易支持重载:

function get<T extends "barcode" | "mqtt">(s: T): T extends "barcode" ? { scan: () => string } : { pan: () => string }
function get(s: "barcode" | "mqtt"): { scan: () => string } | { pan: () => string } {
    return s === "barcode" ?
        { scan: () => "we are scanning" } :
        { pan: () => "we are panning" }
}

get("barcode").scan() // OK
get("mqtt").pan()     // OK
get("barcode").pan() // Error