`T` is not assignable to `SomeType | Exclude<T, SomeType>` where `T` is a generic union type
🔎 Search Terms
"exclude generic"
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about generics and Exclude
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.9.0-dev.20250319#code/C4TwDgpgBAsiAq5oF4oHIAeaoB90jQG4AoYgMwFcA7AY2AEsB7KqMgHnigg2AioBMAzrARIAfAAoMALijwAlLMzY8AUQw0ANhX4QOAGnRYxUAN7EoUAE4RgFKywwkAvkA
💻 Code
type MyType = 'x' | 'y';
function f<T extends MyType>(x: T): 'x' | Exclude<T, 'x'> {
return x;
}
🙁 Actual behavior
TypeScript doesn't treat T and SomeType | Exclude<T, SomeType> as equivalent where T is a generic.
In the above snippet, return x has a type error:
Type 'T' is not assignable to type '"x" | Exclude<T, "x">'.
Type 'MyType' is not assignable to type '"x" | Exclude<T, "x">'.
Type '"y"' is not assignable to type '"x" | Exclude<T, "x">'.
If I remove the generic and write instead type T = MyType, then the code has no errors.
🙂 Expected behavior
As far as I'm aware, there are no values that are assignable to T but not to SomeType | Exclude<T, SomeType>, where T is a union type.
Proof:
The docs for Exclude seem to suggest that a type
Xis assignable toExclude<T, SomeType>(whereTis a union type) if and only ifXis assignable toTANDXis not assignable toSomeType. Therefore,Tis assignable toExclude<T, SomeType>if and only ifTis assignable toT(trivially true) ANDTis not assignable toSomeType.There are two cases:
- If
Tis assignable toSomeType, thenTis assignable toSomeType | Exclude<T, SomeType>.- If
Tis not assignable toSomeType, thenTis assignable toExclude<T, SomeType>as above. Therefore,Tis assignable toSomeType | Exclude<T, SomeType>.Therefore,
Tshould always be assignable toSomeType | Exclude<T, SomeType>.
As such, TypeScript's assertion that Type 'T' is not assignable to type '"x" | Exclude<T, "x">' seems to be mistaken, and I would expect the above snippet to compile without errors.
Additional information about the issue
No response
This is a design limitation. Resolving of conditional types involving generic type arguments is deferred. (Basically, the compiler doesn't know what type T actually is, so it can't figure out what type Exclude<T, ...> is either.)
This would require #33912 (not sure if your case is covered by this).
This issue has been marked as "Design Limitation" and has seen no recent activity. It has been automatically closed for house-keeping purposes.