Enforcing a specific constructor from an interface

This is tricky because you cannot enforce by an interface the shape of a constructor. However, you can use an interface to ensure a class passed by the parameter has a specific constructor. The process requires two interfaces. One is the return type of the construction, and one is the interface used in the parameter:

interface ConstructorReturnType {    
member1: number;
funct(): void;
}
interface EntityConstructor {
new(value: number): ConstructorReturnType;
}

The first interface in this example has two members: one field and one function. The definition of the interface doesn't matter, it can be anything you want to get an instance of the function. The second interface has a constructor function, known as newable. It uses the new keyword with the input parameters and what it needs to create. The type should be the first interface created:

function entityFactory(ctor: EntityConstructor, value: number): ConstructorReturnType {
return new ctor(value);
}

The next step is to create a function that takes the newable function and sets it as a parameter type. Optionally, you can have more parameters. In the example, a value for the constructor is passed. The return type of the function must be the type that the newable function returns. In this function, you can call new followed by the parameter of the interface that has the definition of the newable function. The code instantiates an instance of the class passed by the parameter. Only classes that respect the type contract of the newable function are accepted:

class Implementation1 implements ConstructorReturnType {

public member1: number;

constructor(value: number) {
this.member1 = value;
}

public funct(): void {
}

}
let impl1 = entityFactory(Implementation1, 1);

In the preceding code, the Implementation1 class implements the returned implementation, hence will be a candidate for this function. It also has the constructor that takes a single-number parameter that will be invoked by the function.

On the other hand, the following code does not compile because the class does not inherit the returned type defined by the newable function:

class Implementation2 {
constructor(value: number) { }
}

let impl2 = entityFactory(Implementation2, 1);

An example that might not look valid but that compiles is the following code. It extends the returned class but does not respect the newable function argument that requires it to have a value. It is valid because the definition is only about the returned object and not the constructor. The constructor is called with a parameter, but the class doesn't have to handle it. In the following code, printing the arguments variable shows that it has the 1 value passed as the first parameter even if not explicitly required by the class:

class Implementation3 implements ConstructorReturnType {
public member1: number = 1;
constructor() {
console.log(arguments);
}

public funct(): void {
}
}

let impl3 = entityFactory(Implementation3, 1);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.252.204