I have this piece of code (simplified example):
It's basically an overloaded function that might get 3 different types of object, and will call a different function to each type. I'm differentiating the calls by passing a type parameter that should define the obj type and the return type.
type OBJECT_A = "OBJECT_A";
type OBJECT_B = "OBJECT_B";
type OBJECT_C = "OBJECT_C";
type OBJ_IN = OBJECT_A | OBJECT_B | OBJECT_C
type TYPES_IN = "OBJECT_A" | "OBJECT_B" | "OBJECT_C"
type OBJ_OUT = OBJECT_A | OBJECT_B | OBJECT_C
function someFunction(obj: OBJECT_A, type: "OBJECT_A"): OBJECT_A
function someFunction(obj: OBJECT_B, type: "OBJECT_B"): OBJECT_B
function someFunction(obj: OBJECT_C, type: "OBJECT_C"): OBJECT_C
function someFunction(obj: OBJ_IN, type: TYPES_IN): OBJ_OUT {
if (type === "OBJECT_A") {
return GET_OBJECT_A(obj as OBJECT_A); // <<<<< TYPE ASSERTION HERE
}
else if (type === "OBJECT_B") {
return GET_OBJECT_B(obj as OBJECT_B); // <<<<< TYPE ASSERTION HERE
}
else {
return GET_OBJECT_C(obj as OBJECT_C); // <<<<< TYPE ASSERTION HERE
}
}
function GET_OBJECT_A(obj: OBJECT_A): OBJECT_A {
return obj
}
function GET_OBJECT_B(obj: OBJECT_B): OBJECT_B {
return obj
}
function GET_OBJECT_C(obj: OBJECT_C): OBJECT_C {
return obj
}
Note: In this example I've simplified the return type to be as the same type of the obj. In my real case the return type is kind of a Partial<OBJECT> for each case.
QUESTION
My question is why is Typescript demanding those type assertions? If I'm already checking type === "OBJECT_A, isn't it already clear (from the overload signatures) that obj must be of type OBJECT_A?
Is there a better pattern to handle this? Or should I just stick with the type assertions?
Without the type assertions, Typescript will complain about the calls:
UPDATE:
The idea for the type parameter was to avoid creating functions to check if the obj was type A | B | C, like function IS_OBJECT_A(obj) : obj is OBJECT_A, etc. I would have to check for properties, or something like that. The idea is that when I pass type: "OBJECT_A" the only overload call that allows it should make sure that obj is of course obj: OBJECT_A.
