Stef1611
Stef1611

Reputation: 2387

Writing Function type in typescript: fat arrow and object literal type

I am learning Typescript and I read two ways to write the function type : with a fat arrow or with an object literal.

For example :

let myAdd1: (x: number, y: number) => number =
    function(x: number, y: number): number {return x + y; };

let myAdd2: { (x: number, y: number): number } =
    function(x: number, y: number): number {return x + y; };

What are the reasons to use one rather the other ?

Thanks for answer.

Upvotes: 0

Views: 102

Answers (2)

jcalz
jcalz

Reputation: 327624

Those are identical types written in different ways:

let myAdd1: (x: number, y: number) => number;
type Func = typeof myAdd1;
// type Func = (x: number, y: number) => number
let myAdd2: { (x: number, y: number): number };
type Callable = typeof myAdd2;
// type Callable = (x: number, y: number) => number

You can see that the compiler considers both Func and Callable to be of type (x: number, y: number) => number. Since they're the same, reasons for preferring one to the other are probably subjective and opinion-based.


However, if you start adding properties to the function then the object notation is probably preferable as easier to represent:

let func1: ((x: string) => string) & { color: string } =
  Object.assign((z: string) => z.toUpperCase(), { color: "red" });
type FuncWithProp = typeof func1;
// type FuncWithProp = ((x: string) => string) & { color: string; }
let func2: { (x: string): string; color: string } = 
  Object.assign((z: string) => z.toLowerCase(), { color: "green" });
type CallableWithProp = typeof func2;
// type CallableWithProp = { (x: string): string; color: string }

The types FuncWithProp and CallableWithProp are no longer considered to be identical, but they are mutually assignable (meaning the compiler sees that each extends the other):

type MutuallyExtends<T extends U, U extends V, V = T> = void;
type FuncVsCallableWithprops = MutuallyExtends<FuncWithProp, CallableWithProp>; // okay

So again you can probably use either one in principle, but the FuncWithProp is an intersection type whereas CallableWithProp is a single object type which might behave better in certain edge cases.


Okay, hope that helps; good luck!

Link to code

Upvotes: 1

Christos Lytras
Christos Lytras

Reputation: 37288

The first example is a normal typed function declaration and assignment. The second example uses function overloads shorthand.

Consider we have some normal function overloads:

function myMultiAdd(x: number, y: number): number;
function myMultiAdd(x: number, y: number, z?: number): number {
    return x + y + (z ? z : 0);
}

Both myMultiAdd(1, 2) and myMultiAdd(1, 2, 3) will work. It's inconvenient to use this pattern when having many function overloads because we will repeat the same name again and again, thus typescript has a short function overloads syntax like this:

let myMultiAdd: {
    (x: number, y: number): number,
    (x: number, y: number, z: number): number
} = function (x: number, y: number, z?: number): number {
    return x + y + (z ? z : 0);
}

So, if you don't want to use function overloads, then you should always use the first example to type functions.

Upvotes: 1

Related Questions