Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cedcba9

Browse filesBrowse files
authored
Reset partial memberlist on defered circularity to calculate the correct members (microsoft#20179)
* Reset partial memberlist on defered circularity to calculate the correct members * Remove return type
1 parent 7ad0d7b commit cedcba9
Copy full SHA for cedcba9

6 files changed

+183-8Lines changed: 183 additions & 8 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+15-8Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5123,11 +5123,11 @@ namespace ts {
51235123
return type.resolvedBaseTypes;
51245124
}
51255125

5126-
function resolveBaseTypesOfClass(type: InterfaceType): void {
5127-
type.resolvedBaseTypes = emptyArray;
5126+
function resolveBaseTypesOfClass(type: InterfaceType) {
5127+
type.resolvedBaseTypes = resolvingEmptyArray;
51285128
const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
51295129
if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.Any))) {
5130-
return;
5130+
return type.resolvedBaseTypes = emptyArray;
51315131
}
51325132
const baseTypeNode = getBaseTypeNodeOfClass(type);
51335133
const typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
@@ -5150,24 +5150,31 @@ namespace ts {
51505150
const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
51515151
if (!constructors.length) {
51525152
error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
5153-
return;
5153+
return type.resolvedBaseTypes = emptyArray;
51545154
}
51555155
baseType = getReturnTypeOfSignature(constructors[0]);
51565156
}
51575157

51585158
if (baseType === unknownType) {
5159-
return;
5159+
return type.resolvedBaseTypes = emptyArray;
51605160
}
51615161
if (!isValidBaseType(baseType)) {
51625162
error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
5163-
return;
5163+
return type.resolvedBaseTypes = emptyArray;
51645164
}
51655165
if (type === baseType || hasBaseType(baseType, type)) {
51665166
error(type.symbol.valueDeclaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
51675167
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
5168-
return;
5168+
return type.resolvedBaseTypes = emptyArray;
5169+
}
5170+
if (type.resolvedBaseTypes === resolvingEmptyArray) {
5171+
// Circular reference, likely through instantiation of default parameters
5172+
// (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset
5173+
// as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a
5174+
// partial instantiation of the members without the base types fully resolved
5175+
(type as Type as ResolvedType).members = undefined;
51695176
}
5170-
type.resolvedBaseTypes = [baseType];
5177+
return type.resolvedBaseTypes = [baseType];
51715178
}
51725179

51735180
function areAllOuterTypeParametersApplied(type: Type): boolean {
Collapse file

‎src/compiler/utilities.ts‎

Copy file name to clipboardExpand all lines: src/compiler/utilities.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/* @internal */
44
namespace ts {
55
export const emptyArray: never[] = [] as never[];
6+
export const resolvingEmptyArray: never[] = [] as never[];
67
export const emptyMap: ReadonlyMap<never> = createMap<never>();
78

89
export const externalHelpersModuleNameText = "tslib";
Collapse file
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//// [circularConstraintYieldsAppropriateError.ts]
2+
// https://github.com/Microsoft/TypeScript/issues/16861
3+
class BaseType<T> {
4+
bar: T
5+
}
6+
7+
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
8+
baz: string;
9+
}
10+
11+
class Foo extends NextType<Foo> {
12+
someProp: {
13+
test: true
14+
}
15+
}
16+
17+
const foo = new Foo();
18+
foo.bar.test
19+
20+
//// [circularConstraintYieldsAppropriateError.js]
21+
var __extends = (this && this.__extends) || (function () {
22+
var extendStatics = Object.setPrototypeOf ||
23+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
24+
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
25+
return function (d, b) {
26+
extendStatics(d, b);
27+
function __() { this.constructor = d; }
28+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
29+
};
30+
})();
31+
// https://github.com/Microsoft/TypeScript/issues/16861
32+
var BaseType = /** @class */ (function () {
33+
function BaseType() {
34+
}
35+
return BaseType;
36+
}());
37+
var NextType = /** @class */ (function (_super) {
38+
__extends(NextType, _super);
39+
function NextType() {
40+
return _super !== null && _super.apply(this, arguments) || this;
41+
}
42+
return NextType;
43+
}(BaseType));
44+
var Foo = /** @class */ (function (_super) {
45+
__extends(Foo, _super);
46+
function Foo() {
47+
return _super !== null && _super.apply(this, arguments) || this;
48+
}
49+
return Foo;
50+
}(NextType));
51+
var foo = new Foo();
52+
foo.bar.test;
Collapse file
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
=== tests/cases/compiler/circularConstraintYieldsAppropriateError.ts ===
2+
// https://github.com/Microsoft/TypeScript/issues/16861
3+
class BaseType<T> {
4+
>BaseType : Symbol(BaseType, Decl(circularConstraintYieldsAppropriateError.ts, 0, 0))
5+
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 1, 15))
6+
7+
bar: T
8+
>bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19))
9+
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 1, 15))
10+
}
11+
12+
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
13+
>NextType : Symbol(NextType, Decl(circularConstraintYieldsAppropriateError.ts, 3, 1))
14+
>C : Symbol(C, Decl(circularConstraintYieldsAppropriateError.ts, 5, 15))
15+
>someProp : Symbol(someProp, Decl(circularConstraintYieldsAppropriateError.ts, 5, 26))
16+
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 5, 43))
17+
>C : Symbol(C, Decl(circularConstraintYieldsAppropriateError.ts, 5, 15))
18+
>BaseType : Symbol(BaseType, Decl(circularConstraintYieldsAppropriateError.ts, 0, 0))
19+
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 5, 43))
20+
21+
baz: string;
22+
>baz : Symbol(NextType.baz, Decl(circularConstraintYieldsAppropriateError.ts, 5, 84))
23+
}
24+
25+
class Foo extends NextType<Foo> {
26+
>Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1))
27+
>NextType : Symbol(NextType, Decl(circularConstraintYieldsAppropriateError.ts, 3, 1))
28+
>Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1))
29+
30+
someProp: {
31+
>someProp : Symbol(Foo.someProp, Decl(circularConstraintYieldsAppropriateError.ts, 9, 33))
32+
33+
test: true
34+
>test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15))
35+
}
36+
}
37+
38+
const foo = new Foo();
39+
>foo : Symbol(foo, Decl(circularConstraintYieldsAppropriateError.ts, 15, 5))
40+
>Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1))
41+
42+
foo.bar.test
43+
>foo.bar.test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15))
44+
>foo.bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19))
45+
>foo : Symbol(foo, Decl(circularConstraintYieldsAppropriateError.ts, 15, 5))
46+
>bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19))
47+
>test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15))
48+
Collapse file
+50Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
=== tests/cases/compiler/circularConstraintYieldsAppropriateError.ts ===
2+
// https://github.com/Microsoft/TypeScript/issues/16861
3+
class BaseType<T> {
4+
>BaseType : BaseType<T>
5+
>T : T
6+
7+
bar: T
8+
>bar : T
9+
>T : T
10+
}
11+
12+
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
13+
>NextType : NextType<C, T>
14+
>C : C
15+
>someProp : any
16+
>T : T
17+
>C : C
18+
>BaseType : BaseType<T>
19+
>T : T
20+
21+
baz: string;
22+
>baz : string
23+
}
24+
25+
class Foo extends NextType<Foo> {
26+
>Foo : Foo
27+
>NextType : NextType<Foo, { test: true; }>
28+
>Foo : Foo
29+
30+
someProp: {
31+
>someProp : { test: true; }
32+
33+
test: true
34+
>test : true
35+
>true : true
36+
}
37+
}
38+
39+
const foo = new Foo();
40+
>foo : Foo
41+
>new Foo() : Foo
42+
>Foo : typeof Foo
43+
44+
foo.bar.test
45+
>foo.bar.test : true
46+
>foo.bar : { test: true; }
47+
>foo : Foo
48+
>bar : { test: true; }
49+
>test : true
50+
Collapse file
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// https://github.com/Microsoft/TypeScript/issues/16861
2+
class BaseType<T> {
3+
bar: T
4+
}
5+
6+
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
7+
baz: string;
8+
}
9+
10+
class Foo extends NextType<Foo> {
11+
someProp: {
12+
test: true
13+
}
14+
}
15+
16+
const foo = new Foo();
17+
foo.bar.test

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.