-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Intersection type in template literal is not reduced to its bare type #57918
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
Comments
This comment was marked as resolved.
This comment was marked as resolved.
Correct. Updated. π» |
Trying to differentiate template and string literal types seems only possible by relying on weird implementation-detail corner cases and really isn't a great thing to try to offer. |
It's not just that. This also make it not possible to check for negative number from interaction type. Speaking of which, it would be great if TS can provide those type utilities. I understand nowadays TS team don't want to add new type utils, but these are types closely related to the language, and like you said, most of them requires a lot of hackaround ways to get them to work. |
This comment has been minimized.
This comment has been minimized.
The |
This comment has been minimized.
This comment has been minimized.
Internal implementation details are subject to change at any time. The origin of this type is that someone went looking for places where type identity might be unintentionally exposed, was successful, and then introduced this into the wild before we noticed and could un-expose it without breaking a ton of people. TS doesn't have any defined semantics of "identical" types, and attempts to reverse-engineer one are not going to be successful as a result. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Update on my above comments: I fixed that slightly tangential issue in #61113, which was merged a few days ago (incidentally, also fixing that particular problem with the So to re-focus on the issue at hand: personally, I'm ambivalent whether tagged strings should have their tags removed in a template string. However, the big issue I do see here is that there is no way to remove tags from a literal if you don't know the exact type of the tag(s) in advance. I.e., it is utterly impossible to write an type Evil = 1234 & {a: 0 | 1} & {a: 1 | 2} & {toString: Number['toString']}
type YourFailedAttempt = Untag<Evil> // Expected output: 1234 This means that libraries that do conditional string manipulation, etc. will necessarily fail if the user passes in any tagged primitive. It would be really nice to have some way of stripping arbitrary tags from an arbitrary primitive literal. The very least intrusive fix, I believe, would be to allow the following behavior to work: type TheTag = Evil extends number & infer TAG ? TAG : unknown Critically, |
π Search Terms
template literal, intersection type
π Version & Regression Information
const
template literalΒ #54648β― Playground Link
https://www.typescriptlang.org/play?#code/C4TwDgpgBAysBOBLAdgcwCrggHgNJQgA9gJkATAZygoRVQD4oBeKfIk8qmpNKAMigoAZhHhQAqgCgAkAH4oAbVwAaCQF0CxUpUXjVuNTPkBvAL6aOO44oAKg5FAAGAEmO5TjtQC4oAV2QA1sgA9gDuDqZGUADkJAC2YAA2AIYkADKIJPDJidEyPtHcdBlZOXnSBUVo5T7IEABuopKSoJBQAEoAjMywtGiYkNhVDJIA9KNQkwB6si1YHQBMPXA8GFhDfaj8UNbJPt2m9GMT07Nzbe0AzMubAzjRyQBGAMbRR+OTUDPn0O0ALDdVndsA8XtFtrt9lBDsdPt8fh0AKyAujAlzGZC+OKPUQed4nL6zVq-ABsKP663RmOxuMcEKgeygB3xcLOUCAA
π» Code
π Actual behavior
π Expected behavior
Additional information about the issue
I mentioned this in #54648 after it is closed. It is limiting our ability to write the types that works with string literal and template literal and there is no alternative way to workaround that.
I'm suggesting this issue should be fixed and restore the behavior in 5.0.
Here is my original comment:
This behavior is causing a few types in
type-plus
to fail (e.g.IsTemplateLiteral
,IsStringLiteral
,Omit
,IsNegative
, etc) unional/type-plus#429.In term of soundness, IMO it does make sense that
${string & { a: 1 }}
to be reduced to${string}
.in JS, it would be:
the reasoning being the
toString(): string
remains unchanged thus the resulting type should be safe to reduce.The text was updated successfully, but these errors were encountered: