简体   繁体   中英

Objects type casting in TypeScript

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?

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;

docs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM