Search code examples
javascripttypescriptconstructor

What is FunctionConstructor in typeScript?


I was going through the Typescript Ecmascript source code. I came across this:

interface FunctionConstructor {
    /**
     * Creates a new function.
     * @param args A list of arguments the function accepts.
     */
    new(...args: string[]): Function;
    (...args: string[]): Function;
    readonly prototype: Function;
}

declare var Function: FunctionConstructor;

I am assuming FunctionConstructor is the type of Function's constructor.

We declaring a Function variable which has FunctionConstructor interface. What are the first two parameters in the FunctionConstructor interface? And why would variable Function(a plain JavaScript object deriving from Object) have its type similar to its constructor?

Basically I am trying to understand what is happening behind the scenes. Any help is appreciated. Thanks!


Solution

  • Firstly see Function() constructor

    The Function() constructor creates a new Function object. Calling the constructor directly can create functions dynamically, but suffers from security and similar (but far less significant) performance issues as eval(). However, unlike eval (which may have access to the local scope), the Function constructor creates functions which execute in the global scope only.

    const sum = new Function('a', 'b', 'return a + b');
    
    console.log(sum(2, 6));
    // Expected output: 8
    

    To rephrase: creating functions dynamically is an advanced feature. Use regular functions if possible.

    Having said that:

    remember that variables and types use different namespaces.

    This code is legal

    interface Foo {
      id: number
    }
    
    var Foo = 1;
    

    Thus, var Function: FunctionConstructor is an object that can be used to produce Function objects.

    Interface FunctionConstructor models how Function object can be used:

    • creating a function with new
    // using new(...args: string[]): Function;
    const sum = new Function('a', 'b', 'return a + b');
    console.log(sum(2, 6));
    
    • creating a function without new
    // using (...args: string[]): Function;
    const sum = Function('a', 'b', 'return a + b');
    console.log(sum(2, 6));
    

    prototype: Function is a sign of prototypal inheritance in JS. Object created via Function object will have their __proto__ set to object of type Function, and thus can use methods from this type (can be called etc).

    const sum = Function('a', 'b', 'return a + b');
    console.log(sum(2, 6));
    
    console.log(Function.prototype === sum.__proto__) // true