Closed
Description
TypeScript Version: 2.7.0-dev.20171216
Code
class Base {}
class Derived extends Base {
public derived = true;
}
interface ISetter0<T> {
set(x: T): void;
}
interface ISetter1<T> {
set: (x: T) => void;
}
const derivedSetter0: ISetter0<Derived> = { set: () => null }; // assignment 0
const derivedSetter1: ISetter1<Derived> = { set: () => null }; // assignment 1
let baseSetter0: ISetter0<Base> = derivedSetter0; // assignment 2
let baseSetter1: ISetter1<Base> = derivedSetter1; // assignment 3
baseSetter0 = derivedSetter1; // assignment 4
baseSetter1 = derivedSetter0; // assignment 5
Compiler options:
"compilerOptions": {
"strict": true,
"strictFunctionTypes": true,
},
Expected behavior:
Compilation should fail at assignments 2, 3, 4 and 5.
Actual behavior:
Compilation only fails at assigments 3 and 5.
tsc
output:
test.ts(17,5): error TS2322: Type 'ISetter1<Derived>' is not assignable to type 'ISetter1<Base>'.
Type 'Base' is not assignable to type 'Derived'.
Property 'derived' is missing in type 'Base'.
test.ts(20,1): error TS2322: Type 'ISetter0<Derived>' is not assignable to type 'ISetter1<Base>'.
Types of property 'set' are incompatible.
Type '(x: Derived) => void' is not assignable to type '(x: Base) => void'.
Types of parameters 'x' and 'x' are incompatible.
Type 'Base' is not assignable to type 'Derived'.
Additional Notes:
The expected behavior handles contravariance correctly, the actual behavior not.
This bug could be part of the more general issue “Covariance / Contravariance Annotations”, but a full covariance / contravariance implementation is probably not necessary to fix this bug. It would probably also be fixed if
“Proposal: covariance and contravariance generic type arguments annotations” is implemented.