Coding the same logic in different styles:
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
The compiler recognizes both Func
and Callable
as having a type of
(x: number, y: number) => number
. The preference between them is subjective as they are essentially the same.
If additional properties need to be added, object notation is more convenient:
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 }
While FuncWithProp
and CallableWithProp
are not identical anymore, they can still assign values to each other:
type MutuallyExtends<T extends U, U extends V, V = T> = void;
type FuncVsCallableWithprops = MutuallyExtends<FuncWithProp, CallableWithProp>; // okay
You could use either in various scenarios, but FuncWithProp
represents an intersection type whereas CallableWithProp
is a standalone object type that may perform better in some situations.
Hope this information helps you out! Best of luck!
Link to code