Reset partial memberlist on defered circularity to calculate the correct members (#20179)
* Reset partial memberlist on defered circularity to calculate the correct members * Remove return type
This commit is contained in:
parent
7ad0d7b9fd
commit
cedcba9285
|
@ -5123,11 +5123,11 @@ namespace ts {
|
|||
return type.resolvedBaseTypes;
|
||||
}
|
||||
|
||||
function resolveBaseTypesOfClass(type: InterfaceType): void {
|
||||
type.resolvedBaseTypes = emptyArray;
|
||||
function resolveBaseTypesOfClass(type: InterfaceType) {
|
||||
type.resolvedBaseTypes = resolvingEmptyArray;
|
||||
const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
|
||||
if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.Any))) {
|
||||
return;
|
||||
return type.resolvedBaseTypes = emptyArray;
|
||||
}
|
||||
const baseTypeNode = getBaseTypeNodeOfClass(type);
|
||||
const typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode);
|
||||
|
@ -5150,24 +5150,31 @@ namespace ts {
|
|||
const constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
|
||||
if (!constructors.length) {
|
||||
error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
|
||||
return;
|
||||
return type.resolvedBaseTypes = emptyArray;
|
||||
}
|
||||
baseType = getReturnTypeOfSignature(constructors[0]);
|
||||
}
|
||||
|
||||
if (baseType === unknownType) {
|
||||
return;
|
||||
return type.resolvedBaseTypes = emptyArray;
|
||||
}
|
||||
if (!isValidBaseType(baseType)) {
|
||||
error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
|
||||
return;
|
||||
return type.resolvedBaseTypes = emptyArray;
|
||||
}
|
||||
if (type === baseType || hasBaseType(baseType, type)) {
|
||||
error(type.symbol.valueDeclaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
|
||||
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
|
||||
return;
|
||||
return type.resolvedBaseTypes = emptyArray;
|
||||
}
|
||||
type.resolvedBaseTypes = [baseType];
|
||||
if (type.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
|
||||
(type as Type as ResolvedType).members = undefined;
|
||||
}
|
||||
return type.resolvedBaseTypes = [baseType];
|
||||
}
|
||||
|
||||
function areAllOuterTypeParametersApplied(type: Type): boolean {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
/* @internal */
|
||||
namespace ts {
|
||||
export const emptyArray: never[] = [] as never[];
|
||||
export const resolvingEmptyArray: never[] = [] as never[];
|
||||
export const emptyMap: ReadonlyMap<never> = createMap<never>();
|
||||
|
||||
export const externalHelpersModuleNameText = "tslib";
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//// [circularConstraintYieldsAppropriateError.ts]
|
||||
// https://github.com/Microsoft/TypeScript/issues/16861
|
||||
class BaseType<T> {
|
||||
bar: T
|
||||
}
|
||||
|
||||
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
|
||||
baz: string;
|
||||
}
|
||||
|
||||
class Foo extends NextType<Foo> {
|
||||
someProp: {
|
||||
test: true
|
||||
}
|
||||
}
|
||||
|
||||
const foo = new Foo();
|
||||
foo.bar.test
|
||||
|
||||
//// [circularConstraintYieldsAppropriateError.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
// https://github.com/Microsoft/TypeScript/issues/16861
|
||||
var BaseType = /** @class */ (function () {
|
||||
function BaseType() {
|
||||
}
|
||||
return BaseType;
|
||||
}());
|
||||
var NextType = /** @class */ (function (_super) {
|
||||
__extends(NextType, _super);
|
||||
function NextType() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return NextType;
|
||||
}(BaseType));
|
||||
var Foo = /** @class */ (function (_super) {
|
||||
__extends(Foo, _super);
|
||||
function Foo() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return Foo;
|
||||
}(NextType));
|
||||
var foo = new Foo();
|
||||
foo.bar.test;
|
|
@ -0,0 +1,48 @@
|
|||
=== tests/cases/compiler/circularConstraintYieldsAppropriateError.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/16861
|
||||
class BaseType<T> {
|
||||
>BaseType : Symbol(BaseType, Decl(circularConstraintYieldsAppropriateError.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 1, 15))
|
||||
|
||||
bar: T
|
||||
>bar : Symbol(BaseType.bar, Decl(circularConstraintYieldsAppropriateError.ts, 1, 19))
|
||||
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 1, 15))
|
||||
}
|
||||
|
||||
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
|
||||
>NextType : Symbol(NextType, Decl(circularConstraintYieldsAppropriateError.ts, 3, 1))
|
||||
>C : Symbol(C, Decl(circularConstraintYieldsAppropriateError.ts, 5, 15))
|
||||
>someProp : Symbol(someProp, Decl(circularConstraintYieldsAppropriateError.ts, 5, 26))
|
||||
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 5, 43))
|
||||
>C : Symbol(C, Decl(circularConstraintYieldsAppropriateError.ts, 5, 15))
|
||||
>BaseType : Symbol(BaseType, Decl(circularConstraintYieldsAppropriateError.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(circularConstraintYieldsAppropriateError.ts, 5, 43))
|
||||
|
||||
baz: string;
|
||||
>baz : Symbol(NextType.baz, Decl(circularConstraintYieldsAppropriateError.ts, 5, 84))
|
||||
}
|
||||
|
||||
class Foo extends NextType<Foo> {
|
||||
>Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1))
|
||||
>NextType : Symbol(NextType, Decl(circularConstraintYieldsAppropriateError.ts, 3, 1))
|
||||
>Foo : Symbol(Foo, Decl(circularConstraintYieldsAppropriateError.ts, 7, 1))
|
||||
|
||||
someProp: {
|
||||
>someProp : Symbol(Foo.someProp, Decl(circularConstraintYieldsAppropriateError.ts, 9, 33))
|
||||
|
||||
test: true
|
||||
>test : Symbol(test, Decl(circularConstraintYieldsAppropriateError.ts, 10, 15))
|
||||
}
|
||||
}
|
||||
|
||||
const foo = new Foo();
|
||||
>foo : Symbol(foo, Decl(circularConstraintYieldsAppropriateError.ts, 15, 5))
|
||||
>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))
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
=== tests/cases/compiler/circularConstraintYieldsAppropriateError.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/16861
|
||||
class BaseType<T> {
|
||||
>BaseType : BaseType<T>
|
||||
>T : T
|
||||
|
||||
bar: T
|
||||
>bar : T
|
||||
>T : T
|
||||
}
|
||||
|
||||
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
|
||||
>NextType : NextType<C, T>
|
||||
>C : C
|
||||
>someProp : any
|
||||
>T : T
|
||||
>C : C
|
||||
>BaseType : BaseType<T>
|
||||
>T : T
|
||||
|
||||
baz: string;
|
||||
>baz : string
|
||||
}
|
||||
|
||||
class Foo extends NextType<Foo> {
|
||||
>Foo : Foo
|
||||
>NextType : NextType<Foo, { test: true; }>
|
||||
>Foo : Foo
|
||||
|
||||
someProp: {
|
||||
>someProp : { test: true; }
|
||||
|
||||
test: true
|
||||
>test : true
|
||||
>true : true
|
||||
}
|
||||
}
|
||||
|
||||
const foo = new Foo();
|
||||
>foo : Foo
|
||||
>new Foo() : Foo
|
||||
>Foo : typeof Foo
|
||||
|
||||
foo.bar.test
|
||||
>foo.bar.test : true
|
||||
>foo.bar : { test: true; }
|
||||
>foo : Foo
|
||||
>bar : { test: true; }
|
||||
>test : true
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// https://github.com/Microsoft/TypeScript/issues/16861
|
||||
class BaseType<T> {
|
||||
bar: T
|
||||
}
|
||||
|
||||
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
|
||||
baz: string;
|
||||
}
|
||||
|
||||
class Foo extends NextType<Foo> {
|
||||
someProp: {
|
||||
test: true
|
||||
}
|
||||
}
|
||||
|
||||
const foo = new Foo();
|
||||
foo.bar.test
|
Loading…
Reference in a new issue