diff --git a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt
index 600a58638ed..d8e36e43060 100644
--- a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt
+++ b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt
@@ -94,9 +94,17 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(134,1): error TS2322: Type '(f
Types of parameters 'f' and 'f' are incompatible.
Types of parameters 'x' and 'x' are incompatible.
Type 'Animal' is not assignable to type 'Dog'.
+tests/cases/compiler/strictFunctionTypesErrors.ts(147,5): error TS2322: Type '(cb: (x: Animal) => Animal) => void' is not assignable to type '(cb: (x: Dog) => Animal) => void'.
+ Types of parameters 'cb' and 'cb' are incompatible.
+ Types of parameters 'x' and 'x' are incompatible.
+ Type 'Animal' is not assignable to type 'Dog'.
+tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(cb: (x: Animal) => Animal) => void' is not assignable to type '(cb: (x: Dog) => Animal) => void'.
+ Types of parameters 'cb' and 'cb' are incompatible.
+ Types of parameters 'x' and 'x' are incompatible.
+ Type 'Animal' is not assignable to type 'Dog'.
-==== tests/cases/compiler/strictFunctionTypesErrors.ts (33 errors) ====
+==== tests/cases/compiler/strictFunctionTypesErrors.ts (35 errors) ====
export {}
@@ -360,4 +368,35 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(134,1): error TS2322: Type '(f
!!! error TS2322: Types of parameters 'f' and 'f' are incompatible.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'.
-
\ No newline at end of file
+
+ // Verify that callback parameters aren't loosely checked when types
+ // originate in method declarations
+
+ namespace n1 {
+ class Foo {
+ static f1(x: Animal): Animal { throw "wat"; }
+ static f2(x: Dog): Animal { throw "wat"; };
+ }
+ declare let f1: (cb: typeof Foo.f1) => void;
+ declare let f2: (cb: typeof Foo.f2) => void;
+ f1 = f2;
+ f2 = f1; // Error
+ ~~
+!!! error TS2322: Type '(cb: (x: Animal) => Animal) => void' is not assignable to type '(cb: (x: Dog) => Animal) => void'.
+!!! error TS2322: Types of parameters 'cb' and 'cb' are incompatible.
+!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'.
+ }
+
+ namespace n2 {
+ type BivariantHack = { foo(x: Input): Output }["foo"];
+ declare let f1: (cb: BivariantHack) => void;
+ declare let f2: (cb: BivariantHack) => void;
+ f1 = f2;
+ f2 = f1; // Error
+ ~~
+!!! error TS2322: Type '(cb: (x: Animal) => Animal) => void' is not assignable to type '(cb: (x: Dog) => Animal) => void'.
+!!! error TS2322: Types of parameters 'cb' and 'cb' are incompatible.
+!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'.
+ }
\ No newline at end of file
diff --git a/tests/baselines/reference/strictFunctionTypesErrors.js b/tests/baselines/reference/strictFunctionTypesErrors.js
index 8e338fa030d..d0608f6c1ac 100644
--- a/tests/baselines/reference/strictFunctionTypesErrors.js
+++ b/tests/baselines/reference/strictFunctionTypesErrors.js
@@ -133,7 +133,28 @@ declare let fc1: (f: (x: Animal) => Animal) => void;
declare let fc2: (f: (x: Dog) => Dog) => void;
fc1 = fc2; // Error
fc2 = fc1; // Error
-
+
+// Verify that callback parameters aren't loosely checked when types
+// originate in method declarations
+
+namespace n1 {
+ class Foo {
+ static f1(x: Animal): Animal { throw "wat"; }
+ static f2(x: Dog): Animal { throw "wat"; };
+ }
+ declare let f1: (cb: typeof Foo.f1) => void;
+ declare let f2: (cb: typeof Foo.f2) => void;
+ f1 = f2;
+ f2 = f1; // Error
+}
+
+namespace n2 {
+ type BivariantHack = { foo(x: Input): Output }["foo"];
+ declare let f1: (cb: BivariantHack) => void;
+ declare let f2: (cb: BivariantHack) => void;
+ f1 = f2;
+ f2 = f1; // Error
+}
//// [strictFunctionTypesErrors.js]
"use strict";
@@ -195,3 +216,23 @@ animalCrate = dogCrate; // Error
dogCrate = animalCrate; // Error
fc1 = fc2; // Error
fc2 = fc1; // Error
+// Verify that callback parameters aren't loosely checked when types
+// originate in method declarations
+var n1;
+(function (n1) {
+ var Foo = /** @class */ (function () {
+ function Foo() {
+ }
+ Foo.f1 = function (x) { throw "wat"; };
+ Foo.f2 = function (x) { throw "wat"; };
+ ;
+ return Foo;
+ }());
+ f1 = f2;
+ f2 = f1; // Error
+})(n1 || (n1 = {}));
+var n2;
+(function (n2) {
+ f1 = f2;
+ f2 = f1; // Error
+})(n2 || (n2 = {}));
diff --git a/tests/baselines/reference/strictFunctionTypesErrors.symbols b/tests/baselines/reference/strictFunctionTypesErrors.symbols
index fd28775c5e1..c85c337ca44 100644
--- a/tests/baselines/reference/strictFunctionTypesErrors.symbols
+++ b/tests/baselines/reference/strictFunctionTypesErrors.symbols
@@ -424,3 +424,81 @@ fc2 = fc1; // Error
>fc2 : Symbol(fc2, Decl(strictFunctionTypesErrors.ts, 131, 11))
>fc1 : Symbol(fc1, Decl(strictFunctionTypesErrors.ts, 130, 11))
+// Verify that callback parameters aren't loosely checked when types
+// originate in method declarations
+
+namespace n1 {
+>n1 : Symbol(n1, Decl(strictFunctionTypesErrors.ts, 133, 10))
+
+ class Foo {
+>Foo : Symbol(Foo, Decl(strictFunctionTypesErrors.ts, 138, 14))
+
+ static f1(x: Animal): Animal { throw "wat"; }
+>f1 : Symbol(Foo.f1, Decl(strictFunctionTypesErrors.ts, 139, 15))
+>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 140, 18))
+>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
+>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
+
+ static f2(x: Dog): Animal { throw "wat"; };
+>f2 : Symbol(Foo.f2, Decl(strictFunctionTypesErrors.ts, 140, 53))
+>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 141, 18))
+>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
+>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
+ }
+ declare let f1: (cb: typeof Foo.f1) => void;
+>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 143, 15))
+>cb : Symbol(cb, Decl(strictFunctionTypesErrors.ts, 143, 21))
+>Foo.f1 : Symbol(Foo.f1, Decl(strictFunctionTypesErrors.ts, 139, 15))
+>Foo : Symbol(Foo, Decl(strictFunctionTypesErrors.ts, 138, 14))
+>f1 : Symbol(Foo.f1, Decl(strictFunctionTypesErrors.ts, 139, 15))
+
+ declare let f2: (cb: typeof Foo.f2) => void;
+>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 144, 15))
+>cb : Symbol(cb, Decl(strictFunctionTypesErrors.ts, 144, 21))
+>Foo.f2 : Symbol(Foo.f2, Decl(strictFunctionTypesErrors.ts, 140, 53))
+>Foo : Symbol(Foo, Decl(strictFunctionTypesErrors.ts, 138, 14))
+>f2 : Symbol(Foo.f2, Decl(strictFunctionTypesErrors.ts, 140, 53))
+
+ f1 = f2;
+>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 143, 15))
+>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 144, 15))
+
+ f2 = f1; // Error
+>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 144, 15))
+>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 143, 15))
+}
+
+namespace n2 {
+>n2 : Symbol(n2, Decl(strictFunctionTypesErrors.ts, 147, 1))
+
+ type BivariantHack = { foo(x: Input): Output }["foo"];
+>BivariantHack : Symbol(BivariantHack, Decl(strictFunctionTypesErrors.ts, 149, 14))
+>Input : Symbol(Input, Decl(strictFunctionTypesErrors.ts, 150, 23))
+>Output : Symbol(Output, Decl(strictFunctionTypesErrors.ts, 150, 29))
+>foo : Symbol(foo, Decl(strictFunctionTypesErrors.ts, 150, 41))
+>x : Symbol(x, Decl(strictFunctionTypesErrors.ts, 150, 46))
+>Input : Symbol(Input, Decl(strictFunctionTypesErrors.ts, 150, 23))
+>Output : Symbol(Output, Decl(strictFunctionTypesErrors.ts, 150, 29))
+
+ declare let f1: (cb: BivariantHack) => void;
+>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 151, 15))
+>cb : Symbol(cb, Decl(strictFunctionTypesErrors.ts, 151, 21))
+>BivariantHack : Symbol(BivariantHack, Decl(strictFunctionTypesErrors.ts, 149, 14))
+>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
+>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
+
+ declare let f2: (cb: BivariantHack) => void;
+>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 152, 15))
+>cb : Symbol(cb, Decl(strictFunctionTypesErrors.ts, 152, 21))
+>BivariantHack : Symbol(BivariantHack, Decl(strictFunctionTypesErrors.ts, 149, 14))
+>Dog : Symbol(Dog, Decl(strictFunctionTypesErrors.ts, 89, 33))
+>Animal : Symbol(Animal, Decl(strictFunctionTypesErrors.ts, 87, 8))
+
+ f1 = f2;
+>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 151, 15))
+>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 152, 15))
+
+ f2 = f1; // Error
+>f2 : Symbol(f2, Decl(strictFunctionTypesErrors.ts, 152, 15))
+>f1 : Symbol(f1, Decl(strictFunctionTypesErrors.ts, 151, 15))
+}
diff --git a/tests/baselines/reference/strictFunctionTypesErrors.types b/tests/baselines/reference/strictFunctionTypesErrors.types
index 45deeebabab..1890279258c 100644
--- a/tests/baselines/reference/strictFunctionTypesErrors.types
+++ b/tests/baselines/reference/strictFunctionTypesErrors.types
@@ -480,3 +480,87 @@ fc2 = fc1; // Error
>fc2 : (f: (x: Dog) => Dog) => void
>fc1 : (f: (x: Animal) => Animal) => void
+// Verify that callback parameters aren't loosely checked when types
+// originate in method declarations
+
+namespace n1 {
+>n1 : typeof n1
+
+ class Foo {
+>Foo : Foo
+
+ static f1(x: Animal): Animal { throw "wat"; }
+>f1 : (x: Animal) => Animal
+>x : Animal
+>Animal : Animal
+>Animal : Animal
+>"wat" : "wat"
+
+ static f2(x: Dog): Animal { throw "wat"; };
+>f2 : (x: Dog) => Animal
+>x : Dog
+>Dog : Dog
+>Animal : Animal
+>"wat" : "wat"
+ }
+ declare let f1: (cb: typeof Foo.f1) => void;
+>f1 : (cb: (x: Animal) => Animal) => void
+>cb : (x: Animal) => Animal
+>Foo.f1 : (x: Animal) => Animal
+>Foo : typeof Foo
+>f1 : (x: Animal) => Animal
+
+ declare let f2: (cb: typeof Foo.f2) => void;
+>f2 : (cb: (x: Dog) => Animal) => void
+>cb : (x: Dog) => Animal
+>Foo.f2 : (x: Dog) => Animal
+>Foo : typeof Foo
+>f2 : (x: Dog) => Animal
+
+ f1 = f2;
+>f1 = f2 : (cb: (x: Dog) => Animal) => void
+>f1 : (cb: (x: Animal) => Animal) => void
+>f2 : (cb: (x: Dog) => Animal) => void
+
+ f2 = f1; // Error
+>f2 = f1 : (cb: (x: Animal) => Animal) => void
+>f2 : (cb: (x: Dog) => Animal) => void
+>f1 : (cb: (x: Animal) => Animal) => void
+}
+
+namespace n2 {
+>n2 : typeof n2
+
+ type BivariantHack = { foo(x: Input): Output }["foo"];
+>BivariantHack : (x: Input) => Output
+>Input : Input
+>Output : Output
+>foo : (x: Input) => Output
+>x : Input
+>Input : Input
+>Output : Output
+
+ declare let f1: (cb: BivariantHack) => void;
+>f1 : (cb: (x: Animal) => Animal) => void
+>cb : (x: Animal) => Animal
+>BivariantHack : (x: Input) => Output
+>Animal : Animal
+>Animal : Animal
+
+ declare let f2: (cb: BivariantHack) => void;
+>f2 : (cb: (x: Dog) => Animal) => void
+>cb : (x: Dog) => Animal
+>BivariantHack : (x: Input) => Output
+>Dog : Dog
+>Animal : Animal
+
+ f1 = f2;
+>f1 = f2 : (cb: (x: Dog) => Animal) => void
+>f1 : (cb: (x: Animal) => Animal) => void
+>f2 : (cb: (x: Dog) => Animal) => void
+
+ f2 = f1; // Error
+>f2 = f1 : (cb: (x: Animal) => Animal) => void
+>f2 : (cb: (x: Dog) => Animal) => void
+>f1 : (cb: (x: Animal) => Animal) => void
+}
diff --git a/tests/cases/compiler/strictFunctionTypesErrors.ts b/tests/cases/compiler/strictFunctionTypesErrors.ts
index 95598d9d444..3f86f2529c0 100644
--- a/tests/cases/compiler/strictFunctionTypesErrors.ts
+++ b/tests/cases/compiler/strictFunctionTypesErrors.ts
@@ -133,3 +133,25 @@ declare let fc1: (f: (x: Animal) => Animal) => void;
declare let fc2: (f: (x: Dog) => Dog) => void;
fc1 = fc2; // Error
fc2 = fc1; // Error
+
+// Verify that callback parameters aren't loosely checked when types
+// originate in method declarations
+
+namespace n1 {
+ class Foo {
+ static f1(x: Animal): Animal { throw "wat"; }
+ static f2(x: Dog): Animal { throw "wat"; };
+ }
+ declare let f1: (cb: typeof Foo.f1) => void;
+ declare let f2: (cb: typeof Foo.f2) => void;
+ f1 = f2;
+ f2 = f1; // Error
+}
+
+namespace n2 {
+ type BivariantHack = { foo(x: Input): Output }["foo"];
+ declare let f1: (cb: BivariantHack) => void;
+ declare let f2: (cb: BivariantHack) => void;
+ f1 = f2;
+ f2 = f1; // Error
+}
\ No newline at end of file