Búsqueda de sitios web

¿Cómo hacer que una clase implemente una firma de llamada en Typescript?


He definido la siguiente interfaz en TypeScript:

interface MyInterface {
    () : string;
}

Esta interfaz simplemente introduce una firma de llamada que no toma parámetros y devuelve una cadena. ¿Cómo implemento este tipo en una clase? He intentado lo siguiente:

class MyType implements MyInterface {
    function () : string {
        return "Hello World.";
    }
}

El compilador sigue diciéndome eso

La clase 'MyType' declara la interfaz 'MyInterface' pero no la implementa: la interfaz 'MyInterface' requiere una firma de llamada, pero 'MyType' carece de una

¿Cómo puedo implementar la firma de llamada?

Respuesta #1

En caso de que la interfaz callable deba tener otros métodos, puedes hacerlo así:

interface Greeter {
    (): void;
    setName(name: string): void;
}

class ConsoleGreeter {

    private constructor( // constructable via `create()`
        private name = 'world'
    ) {}

    public call(): void {
        console.log(`Hello ${this.name}!`);
    }

    public setName(name: string) {
        this.name = name;
    }

    public static create(): Greeter {
        const instance = new ConsoleGreeter();
        return Object.assign(
            () => instance.call(),
            {
                setName: (name: string) => instance.setName(name)
                // ... forward other methods
            }
        );
    }
}

const greeter = ConsoleGreeter.create();
greeter(); // prints 'Hello world!'
greeter.setName('Dolly');
greeter(); // prints 'Hello Dolly!'

Desventaja: greeter instanceof ConsoleGreeter es false

Respuesta #2

Las clases no pueden coincidir con esa interfaz. Lo más cercano que puedes obtener, creo, es esta clase, que generará código que coincide funcionalmente con la interfaz (pero no según el compilador).

class MyType implements MyInterface {
  constructor {
    return "Hello";
  }
}
alert(MyType());

Esto generará código funcional, pero el compilador se quejará de que MyType no es invocable porque tiene la firma new()='string' (aunque si lo llamas con new, devolverá un objeto).

Para crear algo que realmente coincida con la interfaz sin que el compilador se queje, tendrás que hacer algo como esto:

var MyType = (() : MyInterface => {
  return function() { 
    return "Hello"; 
  }
})();
alert(MyType());

Artículos relacionados