skip to Main Content

Sorry for the weird title, super hard to word that

I have a few types defined:

type Selected = {
    ID: number
}

type DetailsV1 = {
    Status: number
}
type DetailsV2 = {
    Status: number,
    Date: string
}
type DetailsDTO =
    | DetailsV1
    | DetailsV2

type SelectedDetails = DetailsDTO & Selected

I also have a user defined type guard:

function detailsDTOIsV2(
        details: DetailsDTO
    ): details is DetailsV2{
        return (
            (details as DetailsV2)
                .Date !== undefined
        )
    }

When I have an object typed as SelectedDetails how can I access the .Date property?
Without some sort of type checking I get the Property Date does not exist on type SelectedDetails. But I don’t see how to check the types when SelectedDetails is an intersection type, so is there another way to go about this?

2

Answers


  1. You simply have to narrow to the type that has that property. In this case you do that with the in operator.

    selectedDetails.Date // type error
    
    if ('Date' in selectedDetails) {
      selectedDetails.Date // fine
    }
    

    Here 'prop' in object returns true if that property is exists on that object. And TypeScript will notice this and narrow your union to just the ones that have property.

    See playground

    Login or Signup to reply.
  2. I think there is no way around this.

    The TS Compiler cannot infer whether SelectedDetails will have Date field or no without type guard

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search