How to type Middleware that add meta
attributes?
#4036
-
I am looking at properly typing Mastodon's Redux middlewares, but I am not sure of the proper way. This is prompted by the new versions changing the types and making them stricter. You can have a look at my latest attempt here, with a few different ways I tried: mastodon/mastodon#28585 A quick summary of how they work:
Is it any "good" way of implementing this correctly with Typescript? I end up with either ugly code like this: if (
isAction(action) &&
'skipLoading' in action &&
!action.skipLoading
) { … }
// or
if (
isAction(action) &&
'meta' in action &&
typeof action.meta === 'object' &&
action.meta &&
'sound' in action.meta &&
typeof action.meta.sound === 'string'
) { … } An alternative is defining a custom interface for the action we may have and a type guard, but this is still not very nice, plus I am not sure how it would work if I need to handle some custom meta properties: interface ActionWithMaybeAlertParams extends Action {
skipAlert?: boolean;
skipNotFound?: boolean;
error?: unknown;
}
function isActionCustom(action: unknown): action is ActionWithMaybeAlertParams {
return isAction(action);
} I know this is not very idiomatic RTK code, but our codebase is huge and we are moving it slowly to RTK, I need to not change the behaviour for now. Thanks :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Yeah, both of those look plausible to me. I'd definitely encourage the use of type guards in general - both because you convince TS that the object is of a certain type inside the conditional, and also that the complex checks are encapsulated. Not sure how many places you're repeating these checks, but still worth it even if there's only one place. The other option is to bypass TS's strictness and do something like `if (typeof (action as any)?.meta?.sound === "string"), etc. That would also definitely be worth encapsulating in a typeguard. |
Beta Was this translation helpful? Give feedback.
Yeah, both of those look plausible to me. I'd definitely encourage the use of type guards in general - both because you convince TS that the object is of a certain type inside the conditional, and also that the complex checks are encapsulated. Not sure how many places you're repeating these checks, but still worth it even if there's only one place.
The other option is to bypass TS's strictness and do something like `if (typeof (action as any)?.meta?.sound === "string"), etc. That would also definitely be worth encapsulating in a typeguard.