4

Given a union of:

type Status =
    | "Loading"
    | "Success"
    | "Error"

I was expecting this to work:

type Success = Status extends "Success" ? Status : never;
const s: Success = "Success";

However, the above results in

Type 'string' is not assignable to type 'never'.

Whereas, if I use what I thought was an equivalent:

type E<T, U> = T extends U ? T : never;
type Success = E<Status, "Success">;

const s: Success = "Success";

It compiles without a problem. Now, I know that the E type I've created is pretty much how Extract works. I'd just like to understand, what makes it behave differently in the above two cases.

1 Answer 1

2

It's because the conditional type distributes over the union, so E<"Loading" | "Success" | "Error", "Success"> is resolved as

E<"Loading", "Success"> | E<"Success", "Success"> | E<"Error", "Success">
// "Success"

and not as

"Loading" | "Success" | "Error" extends "Success" ? "Loading" | "Success" | "Error" : never
// never

For more information, see the TypeScript handbook section on Distributive conditional types.

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.