Different compile-time behavior in arrow function vs function in TypeScript interface

Viewed 63

Suppose the following simplified TypeScript snippet:

interface MyInterface {
    callbackLambda: (value: string) => void;
    callbackFunction(value: string): void;
}

type MyType = "MyValue";

const myObject: MyInterface = {
    callbackLambda: (value: MyType): void => {
        console.log(value);
    },
    callbackFunction: (value: MyType): void => {
        console.log(value);
    }
};

myObject.callbackLambda("MyValue");
myObject.callbackFunction("MyValue");

This code doesn't compile because TypeScript says:

Type '(value: MyType) => void' is not assignable to type '(value: string) => void'.
  Types of parameters 'value' and 'value' are incompatible.
    Type 'string' is not assignable to type '"MyValue"'.

So, it looks like the function definition compiles fine but the arrow function definition doesn't.

Here's a repro playground.

I couldn't find the information in the documentation and my initial thought was that it should compile fine. Can anybody explain (and find the relevant documentation) why the function definition compiles fine and not the arrow function in this case?

1 Answers

Are you using the strictFunctionTypes flag? (doc)

Under --strictFunctionTypes function type parameter positions are checked contravariantly instead of bivariantly. [...] The stricter checking applies to all function types, except those originating in method or constructor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array<T>) continue to mostly relate covariantly.

If so, I think the reason is that indeed A => C is not a subtype of B => C just because A is a subtype of B (covariance). Actually, A => C is a supertype of B => C if A is a subtype of B (contravariance).

If it sounds strange, suppose you have a constant washAnimal of type Animal => void. You can't assign a function Dog => void to it, even if Dog ≤ Animal, because you would not be able to call washAnimal passing a Cat.

Here and here you can find explanations of covariance/contravariance that are better than mine.

Related