// Example Code:
type Type1 = {
a: string;
};
type Type2 = {
a: string;
b: number;
};
type Type3 = {
a: string;
b: string;
c: string;
d: object;
};
type Types = Type1 | Type2 | Type3;
function getType(thing: Types) {
// ...
}
function processByType(thingsToProcess: Types) {
if (getType(thingsToProcess) === "type1") {
processType1(thingsToProcess);
} else if (getType(thingsToProcess) === "type2") {
processType2(thingsToProcess);
} else if (getType(thingsToProcess) === "type3") {
processType3(thingsToProcess);
} else {
throw Error("Unknown type");
}
}
function processType1(t: Type1) {}
function processType2(t: Type2) {}
function processType3(t: Type3) {}
In the above code, ts wont let me pass an object of Type
to any function but processType1 since Type1 has attributes in common with the rest.
How can I change my code to make this setup work?
CodePudding user response:
Instead of having if (getType(thingsToProcess) === "type1") {
, perform the comparison inside the function so that the function can be used as a type guard.
// example implementation
function isType<T extends Types>(thing: Types, a: string): thing is T {
return thing.a === a;
}
function processByType(thingsToProcess: Types) {
if (isType<Type1>(thingsToProcess, "type1")) {
processType1(thingsToProcess);
if (isType<Type2>(thingsToProcess, "type2")) {
processType2(thingsToProcess);
if (isType<Type3>(thingsToProcess, "type3")) {
processType3(thingsToProcess);
} else {
throw Error("Unknown type");
}
}