Skip to content

[Discussion] Enums/Unions and exhaustiveness #463

Open
@alex35mil

Description

@alex35mil

As a continuation of the discord discussion regarding enums/unions exhaustiveness.

Docs mention having exhaustive enums and unions is unsafe due to possible gaps between server/client releases. In the case of React Native or web apps with service workers, it makes sense. But in the case of traditional web apps, I would argue the risks are relatively low. And if an app implements version checking (eg, via headers), there is no risk at all.

Also, I have a case when the risk is minimal regardless of the nature of a client. On the backend, I have a macro that generates *Result unions. I'm fairly confident that these unions will never be extended, but still forced to handle #UnselectedUnionMember each time I dispatch a Result (quite often).

If in the case of Unions, #UnselectedUnionMember is an inconvenience. But in the case of enums, _ it might hurt. One of the main reasons we use GraphQL is the ability to sync interfaces between server and client, thanks to the GraphQL type system. I.e., when I extend an enum in the backend schema, I can be confident that after the schema sync, Rescript compiler would poke me in every single place where I need to review my code that depends on the extended enum. But when _ is added, it swallows all new constructors, so it requires manual searching to locate all the places where we depend on this enum to review them.

Proposal

Introduce PPX flags --exhaustive-enums --exhaustive-unions that would allow choosing a strategy of handling enums and unions on per application basis.

It makes sense to have a local attribute @exhaustive that makes unions/enums exhaustive for cases when in general, developers prefer to have a #UnselectedUnionMember seatbelt, but in some cases, it is not needed (like the example with generated Result unions).

What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions