Reputation: 2688
Type casting with enum
works really well in TypeScript until you want to do it via util function. Here is an example:
enum MyTypes {
FIRST = "FIRST",
SECOND = "SECOND",
THIRD = "THIRD"
}
type TFirst = {
type: MyTypes.FIRST
foo: string
}
type TSecond = {
type: MyTypes.SECOND
foo: string
}
type TThird = {
type: MyTypes.THIRD
bar: string
}
type TMyObject = TFirst | TSecond | TThird
const someFunction = (myObject: TMyObject) => {
if (myObject.type === MyTypes.FIRST || myObject.type === MyTypes.SECOND) {
// here typescript knows exactly that myObject is TFirst or TSecond
console.log(myObject.foo)
}
}
const isFirstOrSecondUtil = (myObject: TMyObject): boolean => {
return myObject.type === MyTypes.FIRST || myObject.type === MyTypes.SECOND
}
const otherFunction = (myObject: TMyObject) => {
if (isFirstOrSecondUtil(myObject)) {
// typescript is aware that myObject is TMyObject, but does not know which type exactly
console.log(myObject.foo)
}
}
You can test it in TypeScript Playgroud.
As you can see on line 27 inside someFunction
TypeScript is fully aware that myObject
is of type TFirst
or TSecond
even though that function receives TMyObject
. I am able to use myObject.foo
without any problems since this property both of types have.
On the other hand I am using util function isFirstOrSecondUtil
(which does the same checking as it is done in someFunction
) inside otherFunction
and apparently type checking fails in this case. On line 38 TypeScript does not know which type exactly is myObject
. I would expect to be able to console myObject.foo
, but TypeScript fails with Property 'foo' does not exist on type 'TThird'.
Any suggestion how to do proper type casting via util function?
Upvotes: 2
Views: 79
Reputation: 138287
You can tell Typescript that the boolean returned indicates the type:
const isFirstOrSecondUtil = (myObject: TMyObject): myObject is TFirst | TSecond =>
myObject.type === MyTypes.FIRST || myObject.type === MyTypes.SECOND;
Upvotes: 3