-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Rule proposal: comment-based array exhaustiveness check #7774
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
...yes 😄. This is definitely useful for that niche group. But it's niche nonetheless. Marking as In the meantime, my advice would be to try it out in a third party plugin made using the APIs documented at https://typescript-eslint.io/developers/custom-rules. You can iterate with variants of the comments, core functionality, options, etc. without having to deal with our versioning and breaking changes. |
Why don't people generate types from values, though? const allColors = ["Red"] as const;
type Colors = typeof allColors[number]; |
Yeah there's also this other workaround if you really want a union-type-first: type Colors = "Red" | "Blue" | "Green" | "Fuchsia";
const colorsKeys: Record<Colors, null> = {
Red: null,
Blue: null,
Green: null,
Fuchsia: null,
};
const allColors = Object.keys(colorsKeys) as Colors[]; TS will error if Also works for the object case: type Person = { name: string, age: number };
const personKeys: Array<keyof Person> = Object.keys(
{ name: null, age: null } satisfies Record<keyof Person, null>
) as (keyof Person)[]; There's also methods to convert a union type to a tuple type - but they're pretty unstable right now. It does work though if you want to start with a union type. Just not recommended. |
@bradzacher Yeah, I figured that would likely be the answer but wanted to open the ticket anyway. @Josh-Cena I listed the simple
I referenced these as "dark magic" in my original post, and I think they'll always be "unstable" because tuples are ordered and unions are fundamentally not. Changing the order of types in a union shouldn't break code. |
FWIW, this seems very unlike any ts-eslint rule we have. It's not "enforcing a style" or "catching potential issues", but solely "requesting the type checker to check for a specific variable declaration using a narrower type than actually declared", if that makes sense. For one thing, we've never assigned semantic meaning to comments, other than opting out from checks. |
Yeah in general we don't want to delve into adding lint rules that rely on comments existing. Comments are a cumbersome thing to track and attach and are a clunky way to do things for a general-purpose plugin like ours. It's a different story for a smaller 3rd party plugin to do because it's like "if you want this you can adopt this plugin and the standard it introduces" but when if we were to do it it would come across more as "this is the blessed way to do it in TS", given our size and relationships with the TS team. This is obviously not something we want to do! |
See also: microsoft/TypeScript#53171 |
Ok, yes, agreed up: this isn't ready for typescript-eslint core. I was too optimistic at first 🙂. Again, would love to see a plugin built for this rule! Just we can't accept it in this repository without standardization in the community. Thanks for filing! |
Before You File a Proposal Please Confirm You Have Done The Following...
My proposal is suitable for this project
Description
This rule is rooted in a question that comes up from time-to-time on TS-based help servers, people write code like this:
and ask "how can I get a type error on
colors
if it doesn't include all the colors?". The answer is, as far as the type-checker is concerned, is more-or-less "you can't". (Barring some truly dark magic that converts the union to a tuple and tries to generate all permutations) And I can't really imagine the language adding a check for this.But this is the sort of thing that could be opted into via linting:
The above example is a bit contrived, you could generate the type from the array using
as const
(though it's a bit of an advanced technique). Here's a less silly example:This can be useful for iterating over an object in a type-safe way: iterating
Object.keys
is not safe (due to excess keys) and requires extra casting to use, and in some cases the list of keys is useful absent an actual instance of the object to generate it from.As an example of prior-art, the ts-transformer-keys is a tool people have used to solve this problem in the past (though it requires a non-standard TS runtime), though it
I think a minimum (but still useful) set of rules would be:
// @ensure-exhaustive
Both #2 and especially #3 could be expanded to support more patterns and types (e.g. discriminated unions, perhaps); but I think this minimal set would cover most usages.
This is somewhat niche
Fail Cases
Pass Cases
Additional Info
A bit of evidence that this is a somewhat common request, here's a bunch of times people have asked about this on the Typescript Discord:
https://discord.com/channels/508357248330760243/508357248330760249/1154068959289679973
https://discord.com/channels/508357248330760243/1111330767801438318/1111330767801438318
https://discord.com/channels/508357248330760243/1153379072290869368/1153386393532375181
https://discord.com/channels/508357248330760243/1103350513510121522/1103351629790580766
https://discord.com/channels/508357248330760243/740274647899308052/860400499643121684
Not covered by this limited version of the proposal, would require a discriminated union mode:
https://discord.com/channels/508357248330760243/873402624072880149/923683183210397747
The text was updated successfully, but these errors were encountered: