Skip to content

Commit 0055da6

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

File tree

4 files changed

+78
-14
lines changed

4 files changed

+78
-14
lines changed

src/compiler.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -6611,7 +6611,9 @@ 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()

src/types.ts

+15-13
Original file line numberDiff line numberDiff line change
@@ -1051,21 +1051,23 @@ export class Signature {
10511051
isAssignableTo(target: Signature, checkCompatibleOverride: bool = false): bool {
10521052
let thisThisType = this.thisType;
10531053
let targetThisType = target.thisType;
1054-
if (checkCompatibleOverride) {
1055-
// check kind of `this` type
1056-
if (thisThisType) {
1057-
if (!targetThisType || !thisThisType.canExtendOrImplement(targetThisType)) {
1054+
1055+
if (
1056+
(thisThisType == null && targetThisType != null) ||
1057+
(thisThisType != null && targetThisType == null)
1058+
) {
1059+
return false;
1060+
}else if(thisThisType != null && targetThisType != null){
1061+
if(checkCompatibleOverride){
1062+
// check kind of `this` type
1063+
if(!thisThisType.canExtendOrImplement(targetThisType)){
1064+
return false;
1065+
}
1066+
}else{
1067+
// check `this` type (invariant)
1068+
if(!targetThisType.isAssignableTo(thisThisType)){
10581069
return false;
10591070
}
1060-
} else if (targetThisType) {
1061-
return false;
1062-
}
1063-
} else {
1064-
// check `this` type (invariant)
1065-
if (thisThisType) {
1066-
if (targetThisType != targetThisType) return false;
1067-
} else if (targetThisType) {
1068-
return false;
10691071
}
10701072
}
10711073

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+
}
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)