Home > Enterprise >  Typescript property does not exist on type when using a type where property should exist
Typescript property does not exist on type when using a type where property should exist

Time:06-24

I am using a function which takes a message handler function as an argument. The message handler is defined as:

export declare type MessageHandler = <EventType extends AnyEventName = AnyEventName>(type: AnyEventName, payload: EventPayload<EventType>) => void;

In the code there is also the following definition:

export declare type AnyEventPayload = EventPayload<AnyEventName>;

the message handler I am passing is defined as follows:

(message_type: AnyEventName, payload: AnyEventPayload) => {
  console.log(message_type, payload)
  if (message_type === 'idCheck.applicantStatus' && payload.reviewStatus === 'completed') 
    { 
      router.push('/')
    }
}

However I the IDE complains that Property 'reviewStatus' does not exist on type 'AnyEventPayload'. Property 'reviewStatus' does not exist on type '{}'.ts(2339)

When I hover over AnyEventPayload I get:

(alias) type AnyEventPayload = {} | {
    idDocSetType: string;
    types: string[];
    videoRequired?: string | undefined;
} | {
    idDocSetType: string;
} | {
    applicantId: string;
} | {
    reprocessing: boolean;
    levelName: string;
    creationDate: string;
    expireDate: string;
    reviewStatus: string;
    autoChecked: boolean;
} | {
    ...;
} | {
    ...;
} | {
    ...;
} | SnsError
import AnyEventPayload

reviewStatus is there so I don't understand why it's complaining or How can I fix this error?

CodePudding user response:

AnyEventPayload is a union type (which means that it might be any of those type variations between the union operators (|). Because of this, the reviewStatus property name might not be a part of the type, so in order to safely check that the payload value is of the type that includes that property, you can use the in operator to narrow the type to that specific variation. To do so, you just need to precede the equality check which accesses the property with an expression using the in operator so that TS can be sure that the property exists before trying to access it and compare its value:

TS Playground

if (
  message_type === 'idCheck.applicantStatus'
  // Add the following check to ensure that the property exists in the object
  && 'reviewStatus' in payload
  && payload.reviewStatus === 'completed'
) router.push('/');
  • Related