Skip to content

Commit eba83f4

Browse files
authored
Add related span for mixin constructor error (#28319)
* Add related span for mixin constructor error * Remove unneeded casts * Nicer style
1 parent 92a48d8 commit eba83f4

7 files changed

+150
-2
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5674,7 +5674,18 @@ namespace ts {
56745674
return type.resolvedBaseConstructorType = errorType;
56755675
}
56765676
if (!(baseConstructorType.flags & TypeFlags.Any) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
5677-
error(baseTypeNode.expression, Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
5677+
const err = error(baseTypeNode.expression, Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
5678+
if (baseConstructorType.flags & TypeFlags.TypeParameter) {
5679+
const constraint = getConstraintFromTypeParameter(baseConstructorType);
5680+
let ctorReturn: Type = unknownType;
5681+
if (constraint) {
5682+
const ctorSig = getSignaturesOfType(constraint, SignatureKind.Construct);
5683+
if (ctorSig[0]) {
5684+
ctorReturn = getReturnTypeOfSignature(ctorSig[0]);
5685+
}
5686+
}
5687+
addRelatedInfo(err, createDiagnosticForNode(baseConstructorType.symbol.declarations[0], Diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, symbolToString(baseConstructorType.symbol), typeToString(ctorReturn)));
5688+
}
56785689
return type.resolvedBaseConstructorType = errorType;
56795690
}
56805691
type.resolvedBaseConstructorType = baseConstructorType;

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,6 +2493,10 @@
24932493
"category": "Error",
24942494
"code": 2734
24952495
},
2496+
"Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?": {
2497+
"category": "Error",
2498+
"code": 2735
2499+
},
24962500

24972501
"Import declaration '{0}' is using private name '{1}'.": {
24982502
"category": "Error",

tests/baselines/reference/baseConstraintOfDecorator.errors.txt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,36 @@
11
tests/cases/compiler/baseConstraintOfDecorator.ts(2,5): error TS2322: Type 'typeof decoratorFunc' is not assignable to type 'TFunction'.
22
tests/cases/compiler/baseConstraintOfDecorator.ts(2,40): error TS2507: Type 'TFunction' is not a constructor function type.
3+
tests/cases/compiler/baseConstraintOfDecorator.ts(12,5): error TS2322: Type 'typeof decoratorFunc' is not assignable to type 'TFunction'.
4+
tests/cases/compiler/baseConstraintOfDecorator.ts(12,40): error TS2507: Type 'TFunction' is not a constructor function type.
35

46

5-
==== tests/cases/compiler/baseConstraintOfDecorator.ts (2 errors) ====
7+
==== tests/cases/compiler/baseConstraintOfDecorator.ts (4 errors) ====
68
export function classExtender<TFunction>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction {
79
return class decoratorFunc extends superClass {
810
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
911
~~~~~~~~~~
1012
!!! error TS2507: Type 'TFunction' is not a constructor function type.
13+
!!! related TS2735 tests/cases/compiler/baseConstraintOfDecorator.ts:1:31: Did you mean for 'TFunction' to be constrained to type 'new (...args: any[]) => unknown'?
14+
constructor(...args: any[]) {
15+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
super(...args);
17+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
18+
_instanceModifier(this, args);
19+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20+
}
21+
~~~~~~~~~
22+
};
23+
~~~~~~
24+
!!! error TS2322: Type 'typeof decoratorFunc' is not assignable to type 'TFunction'.
25+
}
26+
27+
class MyClass { private x; }
28+
export function classExtender2<TFunction extends new (...args: string[]) => MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction {
29+
return class decoratorFunc extends superClass {
30+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31+
~~~~~~~~~~
32+
!!! error TS2507: Type 'TFunction' is not a constructor function type.
33+
!!! related TS2735 tests/cases/compiler/baseConstraintOfDecorator.ts:11:32: Did you mean for 'TFunction' to be constrained to type 'new (...args: any[]) => MyClass'?
1134
constructor(...args: any[]) {
1235
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1336
super(...args);

tests/baselines/reference/baseConstraintOfDecorator.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ export function classExtender<TFunction>(superClass: TFunction, _instanceModifie
77
}
88
};
99
}
10+
11+
class MyClass { private x; }
12+
export function classExtender2<TFunction extends new (...args: string[]) => MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction {
13+
return class decoratorFunc extends superClass {
14+
constructor(...args: any[]) {
15+
super(...args);
16+
_instanceModifier(this, args);
17+
}
18+
};
19+
}
1020

1121

1222
//// [baseConstraintOfDecorator.js]
@@ -41,3 +51,24 @@ function classExtender(superClass, _instanceModifier) {
4151
}(superClass));
4252
}
4353
exports.classExtender = classExtender;
54+
var MyClass = /** @class */ (function () {
55+
function MyClass() {
56+
}
57+
return MyClass;
58+
}());
59+
function classExtender2(superClass, _instanceModifier) {
60+
return /** @class */ (function (_super) {
61+
__extends(decoratorFunc, _super);
62+
function decoratorFunc() {
63+
var args = [];
64+
for (var _i = 0; _i < arguments.length; _i++) {
65+
args[_i] = arguments[_i];
66+
}
67+
var _this = _super.apply(this, args) || this;
68+
_instanceModifier(_this, args);
69+
return _this;
70+
}
71+
return decoratorFunc;
72+
}(superClass));
73+
}
74+
exports.classExtender2 = classExtender2;

tests/baselines/reference/baseConstraintOfDecorator.symbols

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,37 @@ export function classExtender<TFunction>(superClass: TFunction, _instanceModifie
2727
};
2828
}
2929

30+
class MyClass { private x; }
31+
>MyClass : Symbol(MyClass, Decl(baseConstraintOfDecorator.ts, 7, 1))
32+
>x : Symbol(MyClass.x, Decl(baseConstraintOfDecorator.ts, 9, 15))
33+
34+
export function classExtender2<TFunction extends new (...args: string[]) => MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction {
35+
>classExtender2 : Symbol(classExtender2, Decl(baseConstraintOfDecorator.ts, 9, 28))
36+
>TFunction : Symbol(TFunction, Decl(baseConstraintOfDecorator.ts, 10, 31))
37+
>args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 10, 54))
38+
>MyClass : Symbol(MyClass, Decl(baseConstraintOfDecorator.ts, 7, 1))
39+
>superClass : Symbol(superClass, Decl(baseConstraintOfDecorator.ts, 10, 85))
40+
>TFunction : Symbol(TFunction, Decl(baseConstraintOfDecorator.ts, 10, 31))
41+
>_instanceModifier : Symbol(_instanceModifier, Decl(baseConstraintOfDecorator.ts, 10, 107))
42+
>instance : Symbol(instance, Decl(baseConstraintOfDecorator.ts, 10, 128))
43+
>args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 10, 142))
44+
>TFunction : Symbol(TFunction, Decl(baseConstraintOfDecorator.ts, 10, 31))
45+
46+
return class decoratorFunc extends superClass {
47+
>decoratorFunc : Symbol(decoratorFunc, Decl(baseConstraintOfDecorator.ts, 11, 10))
48+
>superClass : Symbol(superClass, Decl(baseConstraintOfDecorator.ts, 10, 85))
49+
50+
constructor(...args: any[]) {
51+
>args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 12, 20))
52+
53+
super(...args);
54+
>args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 12, 20))
55+
56+
_instanceModifier(this, args);
57+
>_instanceModifier : Symbol(_instanceModifier, Decl(baseConstraintOfDecorator.ts, 10, 107))
58+
>this : Symbol(decoratorFunc, Decl(baseConstraintOfDecorator.ts, 11, 10))
59+
>args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 12, 20))
60+
}
61+
};
62+
}
63+

tests/baselines/reference/baseConstraintOfDecorator.types

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,38 @@ export function classExtender<TFunction>(superClass: TFunction, _instanceModifie
2929
};
3030
}
3131

32+
class MyClass { private x; }
33+
>MyClass : MyClass
34+
>x : any
35+
36+
export function classExtender2<TFunction extends new (...args: string[]) => MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction {
37+
>classExtender2 : <TFunction extends new (...args: string[]) => MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void) => TFunction
38+
>args : string[]
39+
>superClass : TFunction
40+
>_instanceModifier : (instance: any, args: any[]) => void
41+
>instance : any
42+
>args : any[]
43+
44+
return class decoratorFunc extends superClass {
45+
>class decoratorFunc extends superClass { constructor(...args: any[]) { super(...args); _instanceModifier(this, args); } } : typeof decoratorFunc
46+
>decoratorFunc : typeof decoratorFunc
47+
>superClass : TFunction
48+
49+
constructor(...args: any[]) {
50+
>args : any[]
51+
52+
super(...args);
53+
>super(...args) : void
54+
>super : any
55+
>...args : any
56+
>args : any[]
57+
58+
_instanceModifier(this, args);
59+
>_instanceModifier(this, args) : void
60+
>_instanceModifier : (instance: any, args: any[]) => void
61+
>this : this
62+
>args : any[]
63+
}
64+
};
65+
}
66+

tests/cases/compiler/baseConstraintOfDecorator.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@ export function classExtender<TFunction>(superClass: TFunction, _instanceModifie
66
}
77
};
88
}
9+
10+
class MyClass { private x; }
11+
export function classExtender2<TFunction extends new (...args: string[]) => MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction {
12+
return class decoratorFunc extends superClass {
13+
constructor(...args: any[]) {
14+
super(...args);
15+
_instanceModifier(this, args);
16+
}
17+
};
18+
}

0 commit comments

Comments
 (0)