Christian
Christian

Reputation: 124

TS typed includes() in an array of string unions

Consider the object

type User = {
  uid: 'a' | 'b'
};

const user: User = {
   uid: 'a'
}

If I wanted to easily check for specific uids I could do

["a", "b", "c"].includes(user.uid)

but in this case even though "c" isn't a valid string, TS won't catch it.

How would I tell the includes fn to check against an array of type User["uid"] here?

Upvotes: 1

Views: 222

Answers (1)

brunnerh
brunnerh

Reputation: 184524

I would approach the typing the other way around. You first need the IDs as a real object, otherwise you cannot easily do a run-time check against that.

const uids = ['a', 'b'] as const;

type User = {
  uid: typeof uids[number], // resolves to 'a' | 'b'
};

const user: User = {
   uid: 'a'
}

uids.includes(user.uid);

Playground

To check against a specific subset, a new array variable can be declared:

type UID = typeof uids[number];
const subset: UID[] = ['a', 'b', 'x'];
subset.includes(user.uid);

Here an error would be shown for 'x', as that is not a valid ID. The type alias can help reduce duplication and improves readability.

Upvotes: 1

Related Questions