diff --git a/internal/checker/checker.go b/internal/checker/checker.go index d8de6b0419..94076d5d3d 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -18332,6 +18332,11 @@ func (c *Checker) getBaseTypes(t *Type) []*Type { } } } + // In general, base type resolution always precedes member resolution. However, it is possible + // for resolution of type parameter defaults to cause circularity errors, possibly leaving + // members partially resolved. Here we ensure any such partial resolution is reset. + // See https://github.com/microsoft/TypeScript/issues/16861 for an example. + t.objectFlags &^= ObjectFlagsMembersResolved data.baseTypesResolved = true } return data.resolvedBaseTypes @@ -18395,14 +18400,6 @@ func (c *Checker) resolveBaseTypesOfClass(t *Type) { c.error(t.symbol.ValueDeclaration, diagnostics.Type_0_recursively_references_itself_as_a_base_type, c.TypeToString(t)) return } - // !!! This logic is suspicious. We really shouldn't be un-resolving members after they've been resolved. - // if t.resolvedBaseTypes == resolvingEmptyArray { - // // Circular reference, likely through instantiation of default parameters - // // (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset - // // as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a - // // partial instantiation of the members without the base types fully resolved - // t.members = nil - // } t.AsInterfaceType().resolvedBaseTypes = []*Type{reducedBaseType} } diff --git a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt index e1b56c60f3..0c1bc885d1 100644 --- a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt +++ b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt @@ -1,8 +1,7 @@ circularConstraintYieldsAppropriateError.ts(10,7): error TS2310: Type 'Foo' recursively references itself as a base type. -circularConstraintYieldsAppropriateError.ts(17,5): error TS2339: Property 'bar' does not exist on type 'Foo'. -==== circularConstraintYieldsAppropriateError.ts (2 errors) ==== +==== circularConstraintYieldsAppropriateError.ts (1 errors) ==== // https://github.com/Microsoft/TypeScript/issues/16861 class BaseType { bar: T @@ -21,6 +20,4 @@ circularConstraintYieldsAppropriateError.ts(17,5): error TS2339: Property 'bar' } const foo = new Foo(); - foo.bar.test - ~~~ -!!! error TS2339: Property 'bar' does not exist on type 'Foo'. \ No newline at end of file + foo.bar.test \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt.diff deleted file mode 100644 index c641a134b4..0000000000 --- a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.errors.txt.diff +++ /dev/null @@ -1,20 +0,0 @@ ---- old.circularConstraintYieldsAppropriateError.errors.txt -+++ new.circularConstraintYieldsAppropriateError.errors.txt -@@= skipped -0, +0 lines =@@ - circularConstraintYieldsAppropriateError.ts(10,7): error TS2310: Type 'Foo' recursively references itself as a base type. -- -- --==== circularConstraintYieldsAppropriateError.ts (1 errors) ==== -+circularConstraintYieldsAppropriateError.ts(17,5): error TS2339: Property 'bar' does not exist on type 'Foo'. -+ -+ -+==== circularConstraintYieldsAppropriateError.ts (2 errors) ==== - // https://github.com/Microsoft/TypeScript/issues/16861 - class BaseType { - bar: T -@@= skipped -20, +21 lines =@@ - - const foo = new Foo(); - foo.bar.test -+ ~~~ -+!!! error TS2339: Property 'bar' does not exist on type 'Foo'. \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols index ff1505e022..18d50e726e 100644 --- a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols +++ b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols @@ -42,5 +42,9 @@ const foo = new Foo(); >Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1)) foo.bar.test +>foo.bar.test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15)) +>foo.bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19)) >foo : Symbol(foo, Decl(circularConstraintYieldsAppropriateError.ts, 15, 5)) +>bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19)) +>test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15)) diff --git a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols.diff b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols.diff deleted file mode 100644 index c354fe97a8..0000000000 --- a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.symbols.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.circularConstraintYieldsAppropriateError.symbols -+++ new.circularConstraintYieldsAppropriateError.symbols -@@= skipped -41, +41 lines =@@ - >Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1)) - - foo.bar.test -->foo.bar.test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15)) -->foo.bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19)) - >foo : Symbol(foo, Decl(circularConstraintYieldsAppropriateError.ts, 15, 5)) -->bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19)) -->test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15)) diff --git a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types index 4836cc9017..85c834bf83 100644 --- a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types +++ b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types @@ -37,9 +37,9 @@ const foo = new Foo(); >Foo : typeof Foo foo.bar.test ->foo.bar.test : any ->foo.bar : any +>foo.bar.test : true +>foo.bar : { test: true; } >foo : Foo ->bar : any ->test : any +>bar : { test: true; } +>test : true diff --git a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types.diff b/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types.diff deleted file mode 100644 index e4abb27692..0000000000 --- a/testdata/baselines/reference/submodule/compiler/circularConstraintYieldsAppropriateError.types.diff +++ /dev/null @@ -1,15 +0,0 @@ ---- old.circularConstraintYieldsAppropriateError.types -+++ new.circularConstraintYieldsAppropriateError.types -@@= skipped -36, +36 lines =@@ - >Foo : typeof Foo - - foo.bar.test -->foo.bar.test : true -->foo.bar : { test: true; } -+>foo.bar.test : any -+>foo.bar : any - >foo : Foo -->bar : { test: true; } -->test : true -+>bar : any -+>test : any