如何解析两个或多个String Literal联合类型?

时间:2019-06-24 07:43:23

标签: typescript

我有两种类型的字符串文字:

type U = {
    type: "A1",
    value: number 
} | {
    type: "A2",
    value: string 
};
type V = {
    type: "A1",
    test: (value: number) => void;
} | {
    type: "A2",
    test: (value: string) => void;
}

在函数resolve()中,我试图使用参数类型U的值props调用方法test():

let resolve = (u: U, v: V) => {
    if (u.type === v.type) {
        v.test(u.value)    
    }
}

但是出现错误:

Argument of type 'string | number' is not assignable to parameter of type 'number & string'.
  Type 'string' is not assignable to type 'number & string'.
    Type 'string' is not assignable to type 'number'.

一些解决方法,我必须将检查类型分为:

let resolve = (u: U, v: V) => {
    if ((u.type === "A1" && v.type === "A1")) {
        v.test(u.value)    
    } else if (u.type === "A2" && v.type === "A2") {
        v.test(u.value)
    }
}

是否可以在不检查每种文字类型的情况下声明函数?

1 个答案:

答案 0 :(得分:1)

Typescript不能跟踪这样的相关变量(为此需要jcalz建议correlated record types之类的东西)。

最简单的解决方案是使用类型断言,因为您知道这是有效的:

let resolve = (u: U, v: V) => {
    if (u.type === v.type) {
        v.test(u.value as any)    
    }
}

或更安全的版本断言value的交集(这将确保U中涵盖所有选项):

type UnionToIntersection<U> = 
    (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
let resolve = (u: U, v: V) => {
    if (u.type === v.type) {
        v.test(u.value as UnionToIntersection<U['value']>)    
    }
}