Merge pull request #17922 from Microsoft/baseExpressionTypeParameters
Class type parameters not in scope in base class expression
This commit is contained in:
commit
2b10784415
|
@ -1016,7 +1016,18 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
// The type parameters of a class are not in scope in the base class expression.
|
||||
if (lastLocation === (<ExpressionWithTypeArguments>location).expression && (<HeritageClause>location.parent).token === SyntaxKind.ExtendsKeyword) {
|
||||
const container = location.parent.parent;
|
||||
if (isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & SymbolFlags.Type))) {
|
||||
if (nameNotFoundMessage) {
|
||||
error(errorLocation, Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// It is not legal to reference a class's own type parameters from a computed property name that
|
||||
// belongs to the class. For example:
|
||||
//
|
||||
|
|
|
@ -1912,6 +1912,10 @@
|
|||
"category": "Error",
|
||||
"code": 2560
|
||||
},
|
||||
"Base class expressions cannot reference class type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2561
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
tests/cases/compiler/baseExpressionTypeParameters.ts(10,27): error TS2561: Base class expressions cannot reference class type parameters.
|
||||
|
||||
|
||||
==== tests/cases/compiler/baseExpressionTypeParameters.ts (1 errors) ====
|
||||
// Repro from #17829
|
||||
|
||||
function base<T>() {
|
||||
class Base {
|
||||
static prop: T;
|
||||
}
|
||||
return Base;
|
||||
}
|
||||
|
||||
class Gen<T> extends base<T>() {} // Error, T not in scope
|
||||
~
|
||||
!!! error TS2561: Base class expressions cannot reference class type parameters.
|
||||
class Spec extends Gen<string> {}
|
||||
|
||||
<string>Spec.prop;
|
50
tests/baselines/reference/baseExpressionTypeParameters.js
Normal file
50
tests/baselines/reference/baseExpressionTypeParameters.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
//// [baseExpressionTypeParameters.ts]
|
||||
// Repro from #17829
|
||||
|
||||
function base<T>() {
|
||||
class Base {
|
||||
static prop: T;
|
||||
}
|
||||
return Base;
|
||||
}
|
||||
|
||||
class Gen<T> extends base<T>() {} // Error, T not in scope
|
||||
class Spec extends Gen<string> {}
|
||||
|
||||
<string>Spec.prop;
|
||||
|
||||
//// [baseExpressionTypeParameters.js]
|
||||
// Repro from #17829
|
||||
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 __());
|
||||
};
|
||||
})();
|
||||
function base() {
|
||||
var Base = /** @class */ (function () {
|
||||
function Base() {
|
||||
}
|
||||
return Base;
|
||||
}());
|
||||
return Base;
|
||||
}
|
||||
var Gen = /** @class */ (function (_super) {
|
||||
__extends(Gen, _super);
|
||||
function Gen() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return Gen;
|
||||
}(base())); // Error, T not in scope
|
||||
var Spec = /** @class */ (function (_super) {
|
||||
__extends(Spec, _super);
|
||||
function Spec() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return Spec;
|
||||
}(Gen));
|
||||
Spec.prop;
|
|
@ -1,11 +1,11 @@
|
|||
tests/cases/compiler/inheritFromGenericTypeParameter.ts(1,20): error TS2693: 'T' only refers to a type, but is being used as a value here.
|
||||
tests/cases/compiler/inheritFromGenericTypeParameter.ts(1,20): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/compiler/inheritFromGenericTypeParameter.ts(2,24): error TS2312: An interface may only extend a class or another interface.
|
||||
|
||||
|
||||
==== tests/cases/compiler/inheritFromGenericTypeParameter.ts (2 errors) ====
|
||||
class C<T> extends T { }
|
||||
~
|
||||
!!! error TS2693: 'T' only refers to a type, but is being used as a value here.
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
interface I<T> extends T { }
|
||||
~
|
||||
!!! error TS2312: An interface may only extend a class or another interface.
|
|
@ -1,11 +1,11 @@
|
|||
tests/cases/compiler/typeParameterAsBaseClass.ts(1,20): error TS2693: 'T' only refers to a type, but is being used as a value here.
|
||||
tests/cases/compiler/typeParameterAsBaseClass.ts(1,20): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/compiler/typeParameterAsBaseClass.ts(2,24): error TS2422: A class may only implement another class or interface.
|
||||
|
||||
|
||||
==== tests/cases/compiler/typeParameterAsBaseClass.ts (2 errors) ====
|
||||
class C<T> extends T {}
|
||||
~
|
||||
!!! error TS2693: 'T' only refers to a type, but is being used as a value here.
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
class C2<T> implements T {}
|
||||
~
|
||||
!!! error TS2422: A class may only implement another class or interface.
|
|
@ -1,5 +1,5 @@
|
|||
tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(4,20): error TS2693: 'T' only refers to a type, but is being used as a value here.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(5,24): error TS2693: 'U' only refers to a type, but is being used as a value here.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(4,20): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(5,24): error TS2304: Cannot find name 'U'.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(7,24): error TS2312: An interface may only extend a class or another interface.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(8,28): error TS2312: An interface may only extend a class or another interface.
|
||||
|
||||
|
@ -10,10 +10,10 @@ tests/cases/conformance/types/typeParameters/typeParameterAsBaseType.ts(8,28): e
|
|||
|
||||
class C<T> extends T { }
|
||||
~
|
||||
!!! error TS2693: 'T' only refers to a type, but is being used as a value here.
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
class C2<T, U> extends U { }
|
||||
~
|
||||
!!! error TS2693: 'U' only refers to a type, but is being used as a value here.
|
||||
!!! error TS2304: Cannot find name 'U'.
|
||||
|
||||
interface I<T> extends T { }
|
||||
~
|
||||
|
|
13
tests/cases/compiler/baseExpressionTypeParameters.ts
Normal file
13
tests/cases/compiler/baseExpressionTypeParameters.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Repro from #17829
|
||||
|
||||
function base<T>() {
|
||||
class Base {
|
||||
static prop: T;
|
||||
}
|
||||
return Base;
|
||||
}
|
||||
|
||||
class Gen<T> extends base<T>() {} // Error, T not in scope
|
||||
class Spec extends Gen<string> {}
|
||||
|
||||
<string>Spec.prop;
|
Loading…
Reference in a new issue