Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between arrow function vs normal function inside interface

Tags:

typescript

What is the difference between the type inference of foo1 and foo2 in the code given below:

interface myInterface {
    foo1(args: string): void;
    foo2: (args: string) => void;
}

Is type inference different for both? Also when to use which one?

like image 771
vendettacbs Avatar asked Feb 26 '19 11:02

vendettacbs


People also ask

What is the difference between arrow functions and normal functions?

Since regular functions are constructible, they can be called using the new keyword. However, the arrow functions are only callable and not constructible, i.e arrow functions can never be used as constructor functions. Hence, they can never be invoked with the new keyword.

Why do we use arrow instead of normal function?

arguments object inside the regular functions contains the list of arguments. The arrow function, on the opposite, doesn't define arguments (but you can easily access the arrow function arguments using a rest parameter ... args ).

Should I use function or arrow function?

The takeaway: Function expressions are best for object methods. Arrow functions are best for callbacks or methods like map, reduce, or forEach. You can read more about scopes on MDN. On a fundamental level, arrow functions are simply incapable of binding a value of this different from the value of this in their scope.

What is different in arrow functions?

Arrow functions don't have access to the new.target keyword. Arrow functions aren't suitable for call , apply and bind methods, which generally rely on establishing a scope. Arrow functions cannot be used as constructors. Arrow functions cannot use yield , within its body.


1 Answers

In interfaces, there is almost no difference. You can mix and match both styles, according to your preferences:

interface myInterface {
    foo1(args: string): void;
    foo2: (args: string) => void;
}

class C implements myInterface {
    foo1: (args: string) => void = (args) => {

    }

    foo2(args: string) {

    }
}

Also, both are completely interchangeable at runtime:

declare const i: myInterface;

const c = new C;

// no errors
c.foo1 = i.foo2;
i.foo1 = c.foo2;
c.foo2 = i.foo1;
i.foo2 = c.foo1;

There is one difference affecting type inference: --strictFunctionTypes flag does not apply to methods, so in strict mode methods and function properties have different compatibility rules when their argument and return types are not identical.

Another difference is that you can declare property read-only, to prevent assigning to it. You can't do that with a method (but still, you can declare another type with Readonly<myInterface> which will have all properties and methods read-only).

interface myInterface {
    foo1(args: string): void;
    readonly foo2: (args: string) => void;
}

i.foo2 = c.foo1; // this is an error now

However, in classes, they are different, probably because methods are defined on class prototype objects at runtime, but properties are initialized in the code generated for the constructor, so it's impossible to override property with a method:

class C2 extends C {

    foo1(args: string) { // error:  Class 'C' defines instance member property 'foo1',
                        // but extended class 'C2' defines it as instance member function.

    }

    foo2: (args: string) => void = (args) => { // Ok

    }

}
like image 52
artem Avatar answered Sep 28 '22 08:09

artem