From a2d8781bc9f6235c85f3428dc0f0fdfc7c60f58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 4 Oct 2025 14:20:19 +0200 Subject: [PATCH] Port "Avoid resolving source prop type when the target is `unknown`/`any`" --- internal/checker/relater.go | 4 ++ ...rcularitySelfReferentialGetter3.errors.txt | 16 ----- ...ritySelfReferentialGetter3.errors.txt.diff | 20 ------- .../noCircularitySelfReferentialGetter3.types | 10 ++-- ...rcularitySelfReferentialGetter3.types.diff | 27 --------- ...rcularitySelfReferentialGetter4.errors.txt | 18 ------ ...ritySelfReferentialGetter4.errors.txt.diff | 22 ------- ...oCircularitySelfReferentialGetter4.symbols | 12 ++++ ...ularitySelfReferentialGetter4.symbols.diff | 19 ------ .../noCircularitySelfReferentialGetter4.types | 38 ++++++------ ...rcularitySelfReferentialGetter4.types.diff | 59 ------------------- 11 files changed, 40 insertions(+), 205 deletions(-) delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt.diff delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types.diff delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt.diff delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols.diff delete mode 100644 testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types.diff diff --git a/internal/checker/relater.go b/internal/checker/relater.go index 0551862f18..4f101352ff 100644 --- a/internal/checker/relater.go +++ b/internal/checker/relater.go @@ -4264,6 +4264,10 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast. func (r *Relater) isPropertySymbolTypeRelated(sourceProp *ast.Symbol, targetProp *ast.Symbol, getTypeOfSourceProperty func(sym *ast.Symbol) *Type, reportErrors bool, intersectionState IntersectionState) Ternary { targetIsOptional := r.c.strictNullChecks && targetProp.CheckFlags&ast.CheckFlagsPartial != 0 effectiveTarget := r.c.addOptionalityEx(r.c.getNonMissingTypeOfSymbol(targetProp), false /*isProperty*/, targetIsOptional) + // source could resolve to `any` and that's not related to `unknown` target under strict subtype relation + if effectiveTarget.flags&core.IfElse(r.relation == r.c.strictSubtypeRelation, TypeFlagsAny, TypeFlagsAnyOrUnknown) != 0 { + return TernaryTrue + } effectiveSource := getTypeOfSourceProperty(sourceProp) return r.isRelatedToEx(effectiveSource, effectiveTarget, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) } diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt deleted file mode 100644 index 3a8f1b9818..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -noCircularitySelfReferentialGetter3.ts(1,7): error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -noCircularitySelfReferentialGetter3.ts(3,7): error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. - - -==== noCircularitySelfReferentialGetter3.ts (2 errors) ==== - const a = { - ~ -!!! error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - prop: 42, - get self() { - ~~~~ -!!! error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. - return a; - }, - } satisfies { prop: number; self: any }; - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt.diff deleted file mode 100644 index 6d0d285175..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.errors.txt.diff +++ /dev/null @@ -1,20 +0,0 @@ ---- old.noCircularitySelfReferentialGetter3.errors.txt -+++ new.noCircularitySelfReferentialGetter3.errors.txt -@@= skipped -0, +0 lines =@@ -- -+noCircularitySelfReferentialGetter3.ts(1,7): error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -+noCircularitySelfReferentialGetter3.ts(3,7): error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -+ -+ -+==== noCircularitySelfReferentialGetter3.ts (2 errors) ==== -+ const a = { -+ ~ -+!!! error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -+ prop: 42, -+ get self() { -+ ~~~~ -+!!! error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -+ return a; -+ }, -+ } satisfies { prop: number; self: any }; -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types index 742cbe14d9..0caaac102f 100644 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types +++ b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types @@ -2,19 +2,19 @@ === noCircularitySelfReferentialGetter3.ts === const a = { ->a : any ->{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: any; } ->{ prop: 42, get self() { return a; },} : { prop: number; readonly self: any; } +>a : { prop: number; readonly self: any; } +>{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: { prop: number; readonly self: any; }; } +>{ prop: 42, get self() { return a; },} : { prop: number; readonly self: { prop: number; readonly self: any; }; } prop: 42, >prop : number >42 : 42 get self() { ->self : any +>self : { prop: number; readonly self: any; } return a; ->a : any +>a : { prop: number; readonly self: any; } }, } satisfies { prop: number; self: any }; diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types.diff b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types.diff deleted file mode 100644 index 3de7e98b46..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter3.types.diff +++ /dev/null @@ -1,27 +0,0 @@ ---- old.noCircularitySelfReferentialGetter3.types -+++ new.noCircularitySelfReferentialGetter3.types -@@= skipped -1, +1 lines =@@ - - === noCircularitySelfReferentialGetter3.ts === - const a = { -->a : { prop: number; readonly self: any; } -->{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: { prop: number; readonly self: any; }; } -->{ prop: 42, get self() { return a; },} : { prop: number; readonly self: { prop: number; readonly self: any; }; } -+>a : any -+>{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: any; } -+>{ prop: 42, get self() { return a; },} : { prop: number; readonly self: any; } - - prop: 42, - >prop : number - >42 : 42 - - get self() { -->self : { prop: number; readonly self: any; } -+>self : any - - return a; -->a : { prop: number; readonly self: any; } -+>a : any - - }, - } satisfies { prop: number; self: any }; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt deleted file mode 100644 index f0ab68fa87..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -noCircularitySelfReferentialGetter4.ts(1,7): error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -noCircularitySelfReferentialGetter4.ts(3,7): error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. - - -==== noCircularitySelfReferentialGetter4.ts (2 errors) ==== - const a = { - ~ -!!! error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. - prop: 42, - get self() { - ~~~~ -!!! error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. - return a; - }, - } satisfies { prop: number; self: any }; - - const prop = a.self.self.self.self.self.prop; - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt.diff deleted file mode 100644 index 1116478d50..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.errors.txt.diff +++ /dev/null @@ -1,22 +0,0 @@ ---- old.noCircularitySelfReferentialGetter4.errors.txt -+++ new.noCircularitySelfReferentialGetter4.errors.txt -@@= skipped -0, +0 lines =@@ -- -+noCircularitySelfReferentialGetter4.ts(1,7): error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -+noCircularitySelfReferentialGetter4.ts(3,7): error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -+ -+ -+==== noCircularitySelfReferentialGetter4.ts (2 errors) ==== -+ const a = { -+ ~ -+!!! error TS7022: 'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. -+ prop: 42, -+ get self() { -+ ~~~~ -+!!! error TS7023: 'self' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -+ return a; -+ }, -+ } satisfies { prop: number; self: any }; -+ -+ const prop = a.self.self.self.self.self.prop; -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols index c80d78dcef..92533c3a7f 100644 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols +++ b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols @@ -20,5 +20,17 @@ const a = { const prop = a.self.self.self.self.self.prop; >prop : Symbol(prop, Decl(noCircularitySelfReferentialGetter4.ts, 7, 5)) +>a.self.self.self.self.self.prop : Symbol(prop, Decl(noCircularitySelfReferentialGetter4.ts, 0, 11)) +>a.self.self.self.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>a.self.self.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>a.self.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>a.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>a.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) >a : Symbol(a, Decl(noCircularitySelfReferentialGetter4.ts, 0, 5)) +>self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) +>prop : Symbol(prop, Decl(noCircularitySelfReferentialGetter4.ts, 0, 11)) diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols.diff b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols.diff deleted file mode 100644 index a7092083ce..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.symbols.diff +++ /dev/null @@ -1,19 +0,0 @@ ---- old.noCircularitySelfReferentialGetter4.symbols -+++ new.noCircularitySelfReferentialGetter4.symbols -@@= skipped -19, +19 lines =@@ - - const prop = a.self.self.self.self.self.prop; - >prop : Symbol(prop, Decl(noCircularitySelfReferentialGetter4.ts, 7, 5)) -->a.self.self.self.self.self.prop : Symbol(prop, Decl(noCircularitySelfReferentialGetter4.ts, 0, 11)) -->a.self.self.self.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->a.self.self.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->a.self.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->a.self.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->a.self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) - >a : Symbol(a, Decl(noCircularitySelfReferentialGetter4.ts, 0, 5)) -->self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->self : Symbol(self, Decl(noCircularitySelfReferentialGetter4.ts, 1, 11)) -->prop : Symbol(prop, Decl(noCircularitySelfReferentialGetter4.ts, 0, 11)) diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types index a49b8f970a..ee88891c6a 100644 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types +++ b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types @@ -2,19 +2,19 @@ === noCircularitySelfReferentialGetter4.ts === const a = { ->a : any ->{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: any; } ->{ prop: 42, get self() { return a; },} : { prop: number; readonly self: any; } +>a : { prop: number; readonly self: any; } +>{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: { prop: number; readonly self: any; }; } +>{ prop: 42, get self() { return a; },} : { prop: number; readonly self: { prop: number; readonly self: any; }; } prop: 42, >prop : number >42 : 42 get self() { ->self : any +>self : { prop: number; readonly self: any; } return a; ->a : any +>a : { prop: number; readonly self: any; } }, } satisfies { prop: number; self: any }; @@ -22,18 +22,18 @@ const a = { >self : any const prop = a.self.self.self.self.self.prop; ->prop : any ->a.self.self.self.self.self.prop : any ->a.self.self.self.self.self : any ->a.self.self.self.self : any ->a.self.self.self : any ->a.self.self : any ->a.self : any ->a : any ->self : any ->self : any ->self : any ->self : any ->self : any ->prop : any +>prop : number +>a.self.self.self.self.self.prop : number +>a.self.self.self.self.self : { prop: number; readonly self: any; } +>a.self.self.self.self : { prop: number; readonly self: any; } +>a.self.self.self : { prop: number; readonly self: any; } +>a.self.self : { prop: number; readonly self: any; } +>a.self : { prop: number; readonly self: any; } +>a : { prop: number; readonly self: any; } +>self : { prop: number; readonly self: any; } +>self : { prop: number; readonly self: any; } +>self : { prop: number; readonly self: any; } +>self : { prop: number; readonly self: any; } +>self : { prop: number; readonly self: any; } +>prop : number diff --git a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types.diff b/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types.diff deleted file mode 100644 index 6d42220ca3..0000000000 --- a/testdata/baselines/reference/submodule/compiler/noCircularitySelfReferentialGetter4.types.diff +++ /dev/null @@ -1,59 +0,0 @@ ---- old.noCircularitySelfReferentialGetter4.types -+++ new.noCircularitySelfReferentialGetter4.types -@@= skipped -1, +1 lines =@@ - - === noCircularitySelfReferentialGetter4.ts === - const a = { -->a : { prop: number; readonly self: any; } -->{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: { prop: number; readonly self: any; }; } -->{ prop: 42, get self() { return a; },} : { prop: number; readonly self: { prop: number; readonly self: any; }; } -+>a : any -+>{ prop: 42, get self() { return a; },} satisfies { prop: number; self: any } : { prop: number; readonly self: any; } -+>{ prop: 42, get self() { return a; },} : { prop: number; readonly self: any; } - - prop: 42, - >prop : number - >42 : 42 - - get self() { -->self : { prop: number; readonly self: any; } -+>self : any - - return a; -->a : { prop: number; readonly self: any; } -+>a : any - - }, - } satisfies { prop: number; self: any }; -@@= skipped -20, +20 lines =@@ - >self : any - - const prop = a.self.self.self.self.self.prop; -->prop : number -->a.self.self.self.self.self.prop : number -->a.self.self.self.self.self : { prop: number; readonly self: any; } -->a.self.self.self.self : { prop: number; readonly self: any; } -->a.self.self.self : { prop: number; readonly self: any; } -->a.self.self : { prop: number; readonly self: any; } -->a.self : { prop: number; readonly self: any; } -->a : { prop: number; readonly self: any; } -->self : { prop: number; readonly self: any; } -->self : { prop: number; readonly self: any; } -->self : { prop: number; readonly self: any; } -->self : { prop: number; readonly self: any; } -->self : { prop: number; readonly self: any; } -->prop : number -+>prop : any -+>a.self.self.self.self.self.prop : any -+>a.self.self.self.self.self : any -+>a.self.self.self.self : any -+>a.self.self.self : any -+>a.self.self : any -+>a.self : any -+>a : any -+>self : any -+>self : any -+>self : any -+>self : any -+>self : any -+>prop : any