javascript - ¿Puede una clase de Typescript implementar una interfaz invocable?
Las interfaces de Typescript permiten la definición de una firma de llamada en estilo función de la siguiente manera:
interface A {
(x: number): number;
}
Esto se puede implementar, por ejemplo, con una función:
const a: A = function(x: number): number {
return 1;
}
¿Es posible implementar tal interfaz usando una clase?
Lo he intentado así:
class B implements A {
(x: number): number {
return 1;
}
}
Pero recibo este error:
La clase 'B' implementa incorrectamente la interfaz 'A'. El tipo 'B' no proporciona ninguna coincidencia para la firma '(x: number): number'.ts(2420)
¿Hay alguna manera de implementar este tipo de interfaz usando una clase en Typescript?
Respuesta #1
Esto es posible. En mis proyectos implementé una clase auxiliar Callable combinada con una interfaz con el mismo nombre. La combinación con la interfaz es necesaria para darle a TypeScript las tipificaciones correctas de la firma de la función:
export interface Callable<T extends unknown[] = unknown[], R = unknown> {
(...args: T): R;
}
export class Callable<T extends unknown[] = unknown[], R = unknown> extends Function {
public constructor(func: (...args: T) => R) {
super();
return Object.setPrototypeOf(func, new.target.prototype) as typeof this;
}
}
Usar esta clase es bastante sencillo:
class Test extends Callable<[ number, number ], number> {
public multiplier = 2;
public constructor() {
super((a, b) => (a + b) * this.multiplier);
}
}
const test = new Test();
console.log(test(1, 2)); // Prints 6
test.multiplier = 3;
console.log(test(1, 2)); // Prints 9
Algunas explicaciones:
- Defines los tipos de los argumentos de la función en el primer parámetro de tipo en forma de un array.
[ number, number]en este caso significa que la función espera dos parámetros numéricos. - Defines el tipo de retorno de la función como segundo parámetro de tipo. En este caso, esto es nuevamente
number. - Pasas la función real que se llama al invocar la instancia de la clase como una función al constructor de la superclase
Callable.
