Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Exclude<string, SomeType> not working as expected #47178

Closed
NiloCK opened this issue Dec 17, 2021 · 6 comments
Closed

Exclude<string, SomeType> not working as expected #47178

NiloCK opened this issue Dec 17, 2021 · 6 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@NiloCK
Copy link

NiloCK commented Dec 17, 2021

Possibly this lies between being a Bug and being a blind spot in the documentation (Handbook, in this case), but I can't see any indication in the specification of Exclude that it only works to exclude individual types from a union type. I might guess that this is the case from the provided examples, but probably that's not the intent of the documentation.

Here is a minimal example of what I'm referring to:

Bug Report

🔎 Search Terms

  • exclude utility type
  • exclude from string
  • exclude from type

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about bugs that are not bugs_
  • I was unable to test this on prior versions because time

⏯ Playground Link

Playground link with relevant code

💻 Code

type T0 = Exclude< string, "a">;
//    ^?  (== string)
type T1 = Exclude< "a" | "b", "a">;
//    ^?

let a0 : T0 = "a" // should be excluded?
let a1 : T1 = "a" // works ( ie, the assignment does not work. The _exclude_ works )

🙁 Actual behavior

Exclude did not exclude the supplied ExcludedUnion ("a") from string.

🙂 Expected behavior

Exclude excludes "a" from the defined type. From the handbook:

Exclude<Type, ExcludedUnion>
Constructs a type by excluding from Type all union members that are assignable to ExcludedUnion

@fatcerberus
Copy link

Exclude can’t work on string because there’s no way to represent string & ~"foo" in the type system. It only works to exclude types from a union type.

@NiloCK NiloCK closed this as completed Dec 18, 2021
@NiloCK NiloCK reopened this Dec 18, 2021
@NiloCK
Copy link
Author

NiloCK commented Dec 18, 2021

I am finding this meaning in the wording of the handbook now - it's reference to union members refers both to the (implicit) union members of Type and the union members ExcludedUnion - not just the latter.

there’s no way to represent string & ~"foo" in the type system

... because I'm here - why not? Type system is OK with unions and intersections. What does ~ break?

@fatcerberus
Copy link

... why not? Type system is OK with unions and intersections. What does ~ break?

Q. Why isn't this feature supported?
A. Because nobody implemented it yet.

It doesn't break anything - it's just not something that's supported right now. See #29317.

@JustFly1984
Copy link

I would love to have a type string & not ""
Also number & not 0 would be great

NiloCK added a commit to NiloCK/TypeScript-Website that referenced this issue Dec 18, 2021
making the capabilities / limitations of `Exclude<>` more obvious.

see: microsoft/TypeScript#47178
@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Jan 4, 2022
@RyanCavanaugh
Copy link
Member

Exclude, being a conditional type, is distributive over unions, which is why it works, but TS doesn't have any notion of an "infinite union" to represent all strings.

@NiloCK
Copy link
Author

NiloCK commented Jan 6, 2022

Closing via microsoft/TypeScript-Website#2192

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants