I've been trying to create a function where the function's parameter is a union made from two other unions. I want it so that depending on the string passed into the parameter, a different function fires accordingly. Something like this:
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");
I searched through the internet and the docs and I couldn't find a way to do this runtime type checking. I found some "solutions" for type checking, but they were all written for object types, not strings and unions.
In basic javascript, I could create a const array and check if the string is found inside the array, like so:
const type1 = ["a", "b", "c"];
const type2 = ["x", "y", "z"];
function doSomething(param) {
if (type1.includes(param))
functionForTypeOne();
}
Doing this in TypeScript is kind of a solution, but since I need to create unions from these consts, it feels very inefficient, and doesn't allow me to use the type checking features of the language. I was curious if anyone has a solution for this that I possibly overlooked, or if this is the only way for me to get around my problem.
CodePudding user response:
You can build the unions from your tuples almost automatically, and use a type guard predicate to recover type safety:
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();
}
}
CodePudding user response:
you may check this answer https://stackoverflow.com/a/54061487/2429434 There is no way to do what you want to do with your code.