Skip to content

Commit d5fc165

Browse files
bug fix 2727: class member function type is assigned to a normal function type
1 parent 382aabe commit d5fc165

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

src/compiler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6611,13 +6611,17 @@ export class Compiler extends DiagnosticEmitter {
66116611
if (!overrideInstance.is(CommonFlags.Compiled)) continue; // errored
66126612
let overrideType = overrideInstance.type;
66136613
let originalType = instance.type;
6614-
if (!overrideType.isAssignableTo(originalType)) {
6614+
6615+
assert(originalType.getSignature() != null && overrideType.getSignature() != null);
6616+
if (!(overrideType.getSignature() as Signature).isAssignableTo(originalType.getSignature() as Signature, true)) {
66156617
this.error(
66166618
DiagnosticCode.Type_0_is_not_assignable_to_type_1,
66176619
overrideInstance.identifierNode.range, overrideType.toString(), originalType.toString()
66186620
);
66196621
continue;
66206622
}
6623+
6624+
66216625
// TODO: additional optional parameters are not permitted by `isAssignableTo` yet
66226626
let overrideSignature = overrideInstance.signature;
66236627
let overrideParameterTypes = overrideSignature.parameterTypes;

src/types.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,9 +1062,12 @@ export class Signature {
10621062
}
10631063
} else {
10641064
// check `this` type (invariant)
1065-
if (thisThisType) {
1066-
if (targetThisType != targetThisType) return false;
1067-
} else if (targetThisType) {
1065+
if (
1066+
(thisThisType == null && targetThisType != null) ||
1067+
(thisThisType != null && targetThisType == null)
1068+
) {
1069+
return false;
1070+
} else if (thisThisType != null && targetThisType != null && targetThisType.isAssignableTo(thisThisType)) {
10681071
return false;
10691072
}
10701073
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"asc_flags": [],
3+
"stderr": [
4+
"TS2322: Type '(this: class-member-function-as-parameter/C, i32) => i32' is not assignable to type '(i32) => i32'.",
5+
"TS2322: Type '() => void' is not assignable to type '(this: class-member-function-as-parameter/B) => void'.",
6+
"EOF"
7+
]
8+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
class C {
2+
aa: i32 = 1;
3+
callback(a: i32): i32 {
4+
return this.aa + a + 3;
5+
}
6+
}
7+
8+
function expectCallback(c1: (arg0: i32) => i32): i32 {
9+
return c1(4);
10+
}
11+
12+
export function fut(): i32 {
13+
const c1 = new C();
14+
return expectCallback(c1.callback);
15+
}
16+
17+
fut();
18+
19+
class A {
20+
foo(): void {
21+
console.log("A");
22+
}
23+
}
24+
25+
class B extends A {
26+
foo(): void {
27+
console.log("B");
28+
}
29+
}
30+
31+
function foo(): void {
32+
console.log("nothing");
33+
}
34+
35+
function consume(callback: (this: B) => void): void {
36+
const b = new B();
37+
callback.call(b);
38+
}
39+
40+
export function testNull(): void {
41+
consume(foo); // This should (and does) error; this is fine.
42+
}
43+
44+
export function testA(): void {
45+
const a = new A();
46+
consume(a.foo); // This shouldn't error
47+
}
48+
49+
testNull();
50+
testA();
51+
52+
ERROR("EOF");

0 commit comments

Comments
 (0)