-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Intersection type in template literal is not reduced to its bare type #57918
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. |
@RyanCavanaugh this is the first type I've seen that is not identical to itself via export type Equals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false;
type EqualsItself =
// ^? type EqualsItself = false
Equals<
`${'abc' & { a: 1 }}`,
`${'abc' & { a: 1 }}`
> That wasn't always the case: in v5.0.4 we have the correct So maybe there is something unintentional going on here? I'm unsure if it's covered by this existing issue or it's an entirely different issue, but it does seem like there is something broken, as many type-testing libraries rely on this |
The |
@RyanCavanaugh I agree with your general sentiment, however, that's not quite what I'm trying to get across. Let me simplify and refocus my train of thought by taking out the type ExtendsItself =
// ^? type ExtendsItself = false
(<T>() => T extends `${'a' & { a: 1 }}` ? 1 : 2) extends
(<T>() => T extends `${'a' & { a: 1 }}` ? 1 : 2) ? true : false; If this should not be considered a regression, then we have the seemingly strange situation above where there exists a type that does not extend itself, similar to some kind of Which begs the question: do you consider it a regression, or not? I think the answer to that question will really help to clarify the situation. |
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. |
@RyanCavanaugh yes, I agree with you. But looking at my last comment, can we ignore the concept of What I want to know is: would you consider that a regression or not? |
Or, as they say, a picture's worth a thousand words π : |
Ok, I went ahead and opened a separate issue for the above, since I believe it could be resolved separately from this current issue. |
π 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: