网站搜索

javascript - 找出变量属于哪个联合类型的好方法是什么?


我一直在尝试创建一个函数,其中函数的参数是由另外两个联合类型组成的联合类型。我希望根据传入参数的字符串,不同的函数能够相应触发。类似这样:

type Type1 = "a" | "b" | "c";
type Type2 = "x" | "y" | "z";

function doSomething(param: Type1 | Type2) {
    // if param is a part of the "Type1" union
         functionForTypeOne();
}

doSomething("z");

我在互联网上和文档中搜索了,但找不到进行这种运行时类型检查的方法。我找到了一些类型检查的“解决方案”,但它们都是为对象类型编写的,而不是为字符串和联合类型编写的。

在基本的 JavaScript 中,我可以创建一个 const 数组,并检查字符串是否在数组中找到,如下所示:

const type1 = ["a", "b", "c"];
const type2 = ["x", "y", "z"];

function doSomething(param) {
    if (type1.includes(param))
        functionForTypeOne();
}

在 TypeScript 中这样做确实算是一种解决方案,但由于我需要从这些 const 创建联合类型,这感觉非常低效,而且无法让我使用语言的类型检查功能。我想知道是否有人有我可能忽略的解决方案,或者这是否是我解决问题的唯一方法。

答案#1

你几乎可以自动地从你的元组构建联合类型,并使用类型保护谓词来恢复类型安全性:

const type1 = ["a", "b", "c"] as const; // Assert as const to infer tuple instead of array string[]
const type2 = ["x", "y", "z"] as const;

// Automatically get union type from tuple values
type Type1 = typeof type1[number];
//   ^? "a" | "b" | "c"
type Type2 = typeof type2[number];
//   ^? "x" | "y" | "z"

// Type guard predicate
function isIn<T extends readonly string[]>(val: string, arr: T): val is T[number] {
    return arr.includes(val);
}

function doSomething(param: Type1 | Type2) {
    param
    //^? "a" | "b" | "c" | "x" | "y" | "z"
    if (isIn(param, type1)) {
        param
        //^? "a" | "b" | "c"
        //functionForTypeOne();
    }
}

游乐场链接