Ioan Ungurean
Ioan Ungurean

Reputation: 329

Difference between fat arrow function and normal function type declarations in TypeScript interfaces

Having two interfaces declared in two different ways as below. Is there a difference between those two?

interface IFoo {
  onClick: (id: string) => void
}

interface IBar {
  onClick(id: string): void
}

Upvotes: 1

Views: 82

Answers (1)

Aleksey L.
Aleksey L.

Reputation: 37986

There's a difference in type compatibility with strict function types enabled. Function type parameter positions are checked contravariantly (for "function prop") instead of bivariantly (for method)

interface IFooArrow {
  onClick: (id: string) => void
}

interface IBarArrow {
  onClick: (id: 'bar') => void
}

declare let fooA: IFooArrow;
declare let barA: IBarArrow;

fooA = barA; // error: Type 'string' is not assignable to type '"bar"'

interface IFooMethod {
  onClick(id: string): void
}

interface IBarMethod {
  onClick(id: 'bar'): void
}

declare let fooM: IFooMethod;
declare let barM: IBarMethod;

fooM = barM; // no error

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.

Playground

Upvotes: 2

Related Questions