简体   繁体   中英

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

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) 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?

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('/');

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