-
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
Report primitive type in literal-to-primitive relation complaints #38049
Report primitive type in literal-to-primitive relation complaints #38049
Conversation
@typescript-bot pack this |
Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 035b9ac. You can monitor the build here. |
Do we have a regression for something like this? let x: "hello" | "world";
let y: "world" | number;
y = x; My fear is that this gives an error for |
Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build. |
Ah, correct, that is a regression. I can take that on soon! |
d12b741 excludes type unions from either the source or target types in reporting. Looks like that extends through reporting chains, where either can be unions. |
@@ -1,6 +1,6 @@ | |||
tests/cases/compiler/a.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. | |||
tests/cases/compiler/a.ts(8,11): error TS2538: Type '1n' cannot be used as an index type. | |||
tests/cases/compiler/a.ts(14,1): error TS2322: Type 'bigint' is not assignable to type 'string | number | symbol'. | |||
tests/cases/compiler/a.ts(14,1): error TS2322: Type '123n' is not assignable to type 'string | number | symbol'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, the target is a union.
Type '"text"' is not assignable to type 'T'. | ||
Type 'string' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'. | ||
Type 'string' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'. | ||
Type 'string' is not assignable to type 'T & "text"'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm...
'0' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. | ||
Type '"" | 0' is not assignable to type 'T'. | ||
Type 'string | number' is not assignable to type 'T'. | ||
'"" | 0' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm...
!!! error TS2345: 'T' could be instantiated with an arbitrary type which could be unrelated to '1'. | ||
var r11b = foo3(1, (x: T) => '', 1); // error | ||
~~~~~~~~~~~~ | ||
!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. | ||
!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. | ||
!!! error TS2345: Type '1' is not assignable to type 'T'. | ||
!!! error TS2345: Type 'number' is not assignable to type 'T'. | ||
!!! error TS2345: 'T' could be instantiated with an arbitrary type which could be unrelated to '1'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, one thing I've noticed is that this doesn't work with weird intersections of singleton types and with generics constrained to the type of interest. Maybe instead of forEachType(target, isUnitType)
, try using the following helper function.
function typeCouldHaveNoTopLevelSingletonTypes(type: Type) {
return forEachType(type, worker);
}
function typeCouldHaveNoTopLevelSingletonTypesWorker(type: Type) {
return (type.flags & TypeFlags.Intersection)
? forEach((type as IntersectionType).types, typeCouldHaveNoTopLevelSingletonTypesWorker)
: isUnitType(type) || !!(type.flags & TypeFlags.Instantiable);
}
src/compiler/checker.ts
Outdated
return forEachType(type, typeCouldHaveNoTopLevelSingletonTypesWorker); | ||
} | ||
|
||
function typeCouldHaveNoTopLevelSingletonTypesWorker(type: Type): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I think we're getting there. First, I would move these functions out so that they don't add more to the current closure on every call.
Second, I think we have to go deeper on constraints, and we can get rid of the "Worker" function.
function typeCouldHaveNoTopLevelSingletonTypes(type: Type): boolean {
if (type.flags & TypeFlags.UnionOrIntersection) {
return !!forEach((type as IntersectionType).types, typeCouldHaveNoTopLevelSingletonTypes);
}
if (type.flags & TypeFlags.Instantiable) {
const constraint = getConstraintOfType(type);
if (constraint) {
return typeCouldHaveNoTopLevelSingletonTypes(constraint);
}
}
return isUnitType(type);
}
tests/baselines/reference/constructorImplementationWithDefaultValues2.errors.txt
Outdated
Show resolved
Hide resolved
@JoshuaKGoldberg Do you want to keep working on this? It looks like this just needs a small refactoring suggested by @DanielRosenwasser (although I didn't understand his comment "I think we have to go deeper on constraints".) |
I'd be fine dropping this PR & letting you / someone else pick it up. I was planning on spending some time to really go through and understand the constraints & reportings here, which are a good bit deeper than I realized going in... it'd be better IMO if the PR gets merged before I do that (and I have other PRs that are actually ready for review) 😄. |
I'll take it on |
@@ -32,7 +32,7 @@ tests/cases/compiler/extractInferenceImprovement.ts(28,26): error TS2345: Argume | |||
// Should fail | |||
prop = getProperty2(obj, s); | |||
~ | |||
!!! error TS2345: Argument of type 'unique symbol' is not assignable to parameter of type 'never'. | |||
!!! error TS2345: Argument of type 'typeof s' is not assignable to parameter of type 'never'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this one definitely feels arguable. Not sure if @rbuckton has strong feelings about it, but I don't think it's a blocker.
Fixes #29861.