Skip to content
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

Exclude in typescript behaves differently when substitute with its definition #60973

Open
SHND opened this issue Jan 15, 2025 · 2 comments
Open
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@SHND
Copy link

SHND commented Jan 15, 2025

🔎 Search Terms

site:github.com/microsoft/TypeScript Exclude
site:github.com/microsoft/TypeScript Exclude behaves differently
TypeScript Exclude inconsistent
TypeScript Exclude different
TypeScript Exclude behaves differently expanded

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about "Exclude" and "Distributive Conditional Types"

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAsiAq4IEYoF4qoD5QExRwGYCoAWAKFElgSXw2J1JIFYSA2crq6AfQFEAHgGMANgFcAJhAA88ADRQAqgD50UeFAiDgEAHaSAzsqgB+KHogA3CACcoALg0BubkigAlCIfGjgqDAERCWkZOERIZEVwujUoKAB6BMwSXEp3Lx8-ehoIlC0dfSNcujMLaztHEsj4+KSUnHwiEgoeT29fYGIMAG0YyIBdAt0DY36IfHNLG3sncdRa+uw8EkYyLnqYAEMQACNoLb0oAEsAWzBbAHsbU-1gKAAzS-s9S70AWgBzfTtj4ShhFtDN5TOlqJlOsxegBpE5HeZDbQjYrjSblGZVWGLZL8DweADyHi4QA

💻 Code

type _Exclude<T, U> = T extends U ? never : T;

type MyType1 = 1 | 2 | 3 | 4
type MyType2 = 3 | 4 | 5 | 6

type Result1 = _Exclude<MyType1, MyType2>                   // 1 | 2
type Result2 = MyType1 extends MyType2 ? never : MyType1    // 1 | 2 | 3 | 4
type Result3 = [MyType1] extends MyType2 ? never : MyType1  // 1 | 2 | 3 | 4

// Maybe an improvement for non-generic cases?
type Result4 = [K in MyType1] extends MyType2 ? never : K   // ERROR

🙁 Actual behavior

Using "Distributive Conditional Types" in a generic type behaves differently compared to using concrete types. (Not Referential transparent)

🙂 Expected behavior

"Distributive Conditional Types" always works the same, no matter if it is being used in generic types or not.

Additional information about the issue

If "Distributive Conditional Types" should behave differently, I believe it worth providing a way for non-generic types to be able to distribute over the union type in conditional types, same as how it works in generics. Maybe having a syntax like:

type MyType1 = 1 | 2 | 3 | 4
type MyType2 = 3 | 4 | 5 | 6

type Result4 = [K in MyType1] extends MyType2 ? never : K
@SHND
Copy link
Author

SHND commented Jan 15, 2025

@jcalz
Copy link
Contributor

jcalz commented Jan 15, 2025

This isn’t a bug, it’s the intended behavior of distributive conditional types. The suggestion at the end is a duplicate of or strongly related to #30572.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants