'Typing custom event with typescript
I'm asking for a suggest on how to type correctly the schema for how an EventObject should be, including what's inside the "extendedProps" key.
As of now I've done it like this:
interface ICustomExtendedProps {
privateNote?: string;
publicNote?: string;
owner: { id: number; name: string };
guest: { id: number; name: string };
status: EventStatus;
}
export interface CustomEventInput extends EventInput {
extendedProps?: ICustomExtendedProps;
}
Then I created some mock data using this schema and passed them directly inside the event key in the fullcalendar component.
The thing is that I'm creating various kind of custom views using selfmade eventContent components. But now inside the eventContent callback I get the event as a EventApi object, which loses all the custom types I declared before.
Probably this is really a beginner question, but how am I supposed to have consistency in the types?
edit: I'm adding the eventContent cb snippet
<FullCalendar
views={{
dayGridMonth: {
eventContent: ({ event }) => (
<DayGridMonthCustomView
eventData={event}
onClickHandler={eventClickHandler.bind(null, event)}
/>
)
},
}}
/>
The event argument I get from the callback is of the type EventApi, I'm not losing the data inside the event, I'm losing only the type since fullcalendar doesn't know the shape of the event.
Solution 1:[1]
Double assertion
I use this often in the case of event callbacks, particularly when third party libraries are involved.
For some more details see "TypeScript Deep Dive"'s section on double assertions (github mirror)
<FullCalendar
views={{
dayGridMonth: {
eventContent: ({ event }) => (
<DayGridMonthCustomView
eventData={(event as unknown) as CustomEventInput}
onClickHandler={eventClickHandler.bind(null, event)}
/>
)
},
}}
/>
Is there a better option?
I don't consider this particularly ideal for some reason. Maybe the nature of events and third party libraries will leave the user no choice.
There are two cases I can think of recently that in the official docs that may interest those reading into unknown:
Mixins: Constraints has an example where extra interface data is added to an object:
// The runtime aspect could be manually replicated via // type composition or interface merging. type FreezablePlayer = Player & { shouldFreeze: boolean }; const playerTwo = (new Player() as unknown) as FreezablePlayer; playerTwo.shouldFreeze;TypeScript 4.4's release notes: Control Flow Analysis of Aliased Conditions and Discriminants and Using
unknownin Catch Variables.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
