Preserve error elaboration for indexed access type assignments#3220
Preserve error elaboration for indexed access type assignments#3220WhiteMinds wants to merge 1 commit into
Conversation
|
Maybe I don't have context here, but, I don't find the new messages more helpful than the existing one... |
Consider this example: class A {
declare foo: this["faa"];
declare faa: {key: number|null}
fuu() {
this.foo = {} // vague error
this.foo = {key: "str"} // vague error
}
}
let foo: {key: number|null};
foo = {} // precise error
foo = {key: "str"} // precise errorBoth assign to the same underlying type |
| if target.flags&TypeFlagsIndexedAccess == 0 { | ||
| r.errorChain = nil | ||
| } | ||
| r.reportError(diagnostics.X_0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, targetType, generalizedSourceType) |
There was a problem hiding this comment.
Looking at the error in general, it looks pretty confusing to have this message anywhere other than at the bottom of an elaboration.
Maybe guard all of this in an if r.errorChain != nil
There was a problem hiding this comment.
Do you mean skipping the entire "could be instantiated..." elaboration when errorChain already has specific diagnostics? Something like adding r.errorChain == nil to the outer guard:
if targetFlags&TypeFlagsTypeParameter != 0 && target != r.c.markerSuperTypeForCheck && target != r.c.markerSubTypeForCheck && r.errorChain == nil {So when the constraint comparison has already produced precise errors (e.g., missing property or type mismatch), we skip the generic message entirely instead of prepending it.
Before (current):
Type '{}' is not assignable to type 'this["faa"]'.
'this["faa"]' could be instantiated with an arbitrary type which could be unrelated to '{}'.
After:
Type '{}' is not assignable to type 'this["faa"]'.
Property 'key' is missing in type '{}' but required in type '{ key: number | null; }'.
Type '{ key: string; }' is not assignable to type 'this["faa"]'.
Type '{ key: string; }' is not assignable to type '{ key: number | null; }'.
Types of property 'key' are incompatible.
Type 'string' is not assignable to type 'number'.
There was a problem hiding this comment.
No, I was thinking the opposite (r.errorChain != nil, not r.errorChain == nil). The idea is to only override the chain with the specialized error if there was a chain to begin with, but only drop the rest of the chain if the target type isn't an indexed access type.
There was a problem hiding this comment.
Thanks for the clarification. Implemented as suggested: guarded the whole block with r.errorChain != nil, and only clearing the chain for non-indexed-access targets in the default branch.
if targetFlags&TypeFlagsTypeParameter != 0 && ... && r.errorChain != nil {
switch {
case ...:
r.reportError(different_subtype...)
case ...:
r.reportError(different_subtype...)
default:
if target.flags&TypeFlagsIndexedAccess == 0 {
r.errorChain = nil
}
r.reportError(arbitrary_type...)
}
}This affects ~196 baselines since the generic message is now skipped when there's no prior error chain.
Net effect is ~600 fewer lines across baselines, removing cases where "could be instantiated" appeared alone without specific context.
1c9829a to
9c6d671
Compare
When assigning to an indexed access type like this["faa"], the checker resolves the constraint and performs a structural comparison that generates specific error messages (e.g., missing properties or type mismatches). However, reportRelationError unconditionally clears errorChain before reporting the generic "could be instantiated with an arbitrary type" message, discarding the useful elaboration. Only add the specialized type parameter elaboration when there's already an error chain from the constraint comparison. When the target is an indexed access type, preserve the existing chain so users see the specific details; otherwise, replace it with the generic message. When no error chain exists, skip the elaboration entirely — the generic message is confusing when it appears alone without specific context. Fixes microsoft/TypeScript#63206
9c6d671 to
f2c2423
Compare
Fixes microsoft/TypeScript#63206
Problem
When assigning to an indexed access type (e.g.
this["faa"]),reportRelationErrorunconditionally clearserrorChainbefore reporting the generic "could be instantiated with an arbitrary type" message, discarding the specific elaboration already computed from the constraint comparison (missing properties, type mismatches, etc.).Fix
Preserve
errorChainwhen the target is anIndexedAccesstype, so users see both the generic message and the specific details.Before
After
Two existing baselines updated to reflect the additional elaboration (no errors removed, only more specific detail added).