-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Exhaustive array on union type #53171
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
You can do this today with no runtime impact: interface MyInterface {
foo: string;
bar: string;
// missing: string;
}
interface CheckForMissing<Arr extends readonly unknown[], Keys extends Arr[number]> { }
interface CheckForExcess<Arr extends readonly Keys[], Keys> { }
const keys = ['foo', 'bar'/*, 'baz'*/] as const;
{
type CheckKeys1 = CheckForMissing<typeof keys, keyof MyInterface>;
type CheckKeys2 = CheckForExcess<typeof keys, keyof MyInterface>;
} |
Oh cool! That's a little less ergonomic than what I was thinking, but that's fine given this is a less common use case. Thank you for the quick response! |
It's possible there's a more clever solution to do it in 1 line; maybe hit up the folks in the Discord if they're looking for a challenge. |
I was nerd sniped by a related issue and found these: |
Since I too stumbled down this particular rabbit hole, other readers might be interested in this library: |
Suggestion
Something that I've needed from time to time is a way to check that an array contains all the keys on an interface. Right now I can use
(keyof SomeType)[]
to verify that there are no typos/unknown keys, but there's no (easy) way to ensure that the array is exhaustive. I propose a new built-in type,ExhaustiveArray<SomeUnion>
, to do that.🔍 Search Terms
tuple, complete list, all keys, all union members, array
✅ Viability Checklist
My suggestion meets these guidelines:
ExhaustiveArray
are in Java)⭐ Suggestion
I'd like a way to check that an array contains all the keys on an interface. Right now I can do this:
...which will tell me if I've mistyped a key, but it won't tell me if a key is missing. So it's not future-proof if I add a new key to
MyInterface
. It'd be nice if I could do something like this instead:The order of elements doesn't matter, but type-checking fails if the array doesn't contain exactly 1 of every union member. This is a benefit over
ToTuple<SomeUnion>
or something that depends on TypeScript's internal order of union members.Generally, for a union
X
with 2 members,ExhaustiveArray<X>
behaves the same as tuple type[X, X]
:It is an error to pass a union that contains a non-literal type:
I'm not sure how I'd handle optional keys, but given
keyof
doesn't preserve that info anyway, it's probably moot. Maybe something like this?📃 Motivating Example
💻 Use Cases
There is an existing way to do this (see stackoverflow answer), but the proposed solution is roundabout and affects the compiled code (introduces an unnecessary curried function call).
Other solutions might attempt to turn the union into a tuple. This depends on TypeScript's internal union member order, and these functions tend to be recursive which means they may fail for large unions.
The use case that motivated this was an attempt to iterate over a subset of keys in an object, to clear all errors from a state object:
The text was updated successfully, but these errors were encountered: