Reputation: 2387
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
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!
Upvotes: 1
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