3

I have the following type:

type Test = {
  roles: ["nonProfit"];
  nonProfitPrivateDetails: NonProfitPrivateDetails;
} | {
  roles: ["artist"];
  artistPrivateDetails: ArtistPrivateDetails;
} | {
  roles: ["artist", "nonProfit"];
  nonProfitPrivateDetails: NonProfitPrivateDetails;
  artistPrivateDetails: ArtistPrivateDetails;
}

However, when I try to use Array includes on it, the type isn't being inferred:

const t: Test = null as any
t.roles.includes("artist") // fails to compile. 

It fails because "Argument of type 'string' is not assignable to parameter of type 'never'".

IntelliSence is showing includes as a type of: Array<T>.includes(searchElement: never, fromIndex: number | undefined): boolean.

I think I'm just going to have to write custom type guards instead of using includes, but I'd like to understand why this doesn't work.

Thanks!

1
  • Basically you are putting roles in a quantum superposition where it is every single type it can possibly be at once, and simply put, you are never guaranteed to get anything from that :D Commented Aug 16, 2022 at 20:31

1 Answer 1

2

A union of functions or like here a method on a union of type, is only safe to invoke it with an intesection of parameters which in this case resolves to never.

Since roles: ["nonProfit"] | ["artist"] | ["artist", "nonProfit"], there is no intersection hence the never.

One possible fix for that, make the role an enum / a type :

type Role = "nonProfit" | "artist"

type Test = {
  roles: Array<Role>;
  nonProfitPrivateDetails: NonProfitPrivateDetails;
} | {
  roles: Array<Role>;
  artistPrivateDetails: ArtistPrivateDetails;
} | {
  roles: Array<Role>;
  nonProfitPrivateDetails: NonProfitPrivateDetails;
  artistPrivateDetails: ArtistPrivateDetails;
}

declare const t: Test;
t.roles.includes("artist") // ok
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.