Sam
Sam

Reputation: 133

unexpected behavior in covariance/contra-variance like assignment of typescript

I'm new to typescript and I find something unexpected about covariance/contra-variance like behavior.

here's a code snippet:

interface Func1 {
    (): { prop1: string }
}

// assignment similar to covariance
var f1: Func1 = function () { return { prop1: "", prop2: 0 }; }

interface Func2 {
    ({prop1: string, prop2: number}): void;
}

// assignment similar to contra-variance
var f3: Func3 = function (a: { prop1: string }) { }

interface Func3 {
    ({prop1: string}): void;
}

// assignment violates principle of contra-variance.
// expect a compiling error but there isn't.
var f3: Func3 = function (a: { prop1: string, prop2: number }) { alert(a.prop2); }

// here occurs a non-existing field accessing
// it might be unexpected and was possible to be eliminated by static checking on assignment to 'f3'.
f3({ prop1: "" }); 

assignment to f1 is ok since the return value of anonymous function can be assigned to return value type of Func1.

assignment to f2 is ok too since argument fed to Func2 type can be assigned to argument 'a' of the anonymous function.

assignment to f3 should be fail because argument fed to Func3 type can't be assigned to argument 'a' of the anonymous function so I expect the compiler raises an error but it actually doesn't.

this leads to an unexpected accessing violation when call f3.

my question is, is the behavior expected or it's the defect of typescript design/implementation?

Upvotes: 2

Views: 268

Answers (1)

basarat
basarat

Reputation: 276195

// assignment violates principle of contra-variance. // expect a compiling error but there isn't.

This is common issue and is documented : https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Type%20Compatibility.md#function-argument-bivariance

Basically it allows convenience for adding event listeners (a fairly common JS task that would be hard to port to TypeScript if the language pulled the slider further towards safety)

Upvotes: 1

Related Questions