首页 > 解决方案 > 如何解析两个或多个字符串文字联合类型?

问题描述

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

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 的 value 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)
    }
}

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

标签: typescript

解决方案


Typescript 无法像这样跟踪相关变量(为此需要 jcalz 对相关记录类型的建议)。

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

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']>)    
    }
}

推荐阅读