#Guessing generics with property checks

16 messages · Page 1 of 1 (latest)

compact geyser
#

Hey, I have the type following:

export enum AutomationActionType {
    RoleAdd = 1,
    RoleRemove = 2,
    Message = 3,
}

export type AnyAutomationActionType = AutomationActionType.RoleAdd | AutomationActionType.RoleRemove | AutomationActionType.Message;

export type AutomationComponentData<
    T extends AutomationActionType = AnyAutomationActionType
> = {
    componentType: ComponentType;
    actionType: T;
    label: string;
    data: T extends AutomationActionType.RoleAdd
        ? AutomationRoleActionData
        : T extends AutomationActionType.RoleRemove
        ? AutomationRoleActionData
        : T extends AutomationActionType.Message
        ? AutomationMessageActionData : T
};

And I wanted to check the type of AutomationComponentData with:

if (component.actionType === AutomationActionType.RoleAdd)

But still, ts does not recognize component as AutomationActionType<AutomationActionType.RoleAdd> but AutomationActionType<AnyAutomationActionType>.
I have no idea if i am doing a good practice with generics.
any suggestion on checking type of generics as I intend?

arctic canopy
#

T could be a union of the enum values, you would need an interface there to obtain all possible values
a discriminated union would probably be easier to work with as a whole though, not using generics at all

#

!hb discriminated union

thorny stratusBOT
compact geyser
arctic canopy
#

why do you consider it looking "fancy" as important?

#

a discriminated union is the most usable and lines up with what you want to do

compact geyser
#

not only appearance, but also maintenance purposes I guess?
If I had many properties and I happened to make a change with it, then I will have to change everything. That's why I moved to generics,
Since I am not very familiar with generics, guess you're right, maybe much easier to use unions.

arctic canopy
#
interface ActionData {
  [AutomationActionType.RoleAdd]: AutomationRoleActionData;
  [AutomationActionType.RoleRemove]: AutomationRoleActionData;
  [AutomationActionType.Message]: AutomationMessageActionData;
}

export type AutomationComponentData<
    T extends AutomationActionType = AutomationActionType
> = {
    actionType: T;
    data: ActionData[T];
}
```this is basically what i mean by an interface, it maps the enum values to the respective types so you handle unions correctly, it doesn't allow narrowing though since generics allow unions in the first place
#

using a discriminated union for the whole structure solves that

#

btw, AnyAutomationActionType is kinda useless. it's the same as just AutomationActionType itself

arctic canopy
compact geyser
compact geyser
arctic canopy
#

(please don't use that you'll end up with other issues, just use the discriminated union)

compact geyser
#

yeah will do, don't worry, Im tired enough for this issue