c# - overload - Declarar un tipo de delegado en Typescript
typescript string vs string (4)
Ahora publico y uso @steelbreeze/delegate ; tiene algunas limitaciones en comparación con el delegado de C #, ya que es inmutable, pero de lo contrario funciona bien (y cuando se llama devuelve resultados de todas las funciones llamadas).
Te permite escribir código como:
import { create as delegate } from "@steelbreeze/delegate";
function world(s: string) {
console.log(s + " world");
}
const one = delegate(s => console.log(s + " Hello world"));
const two = delegate(s => console.log(s + " Hello"), world);
one("A");
two("B");
delegate(one, two)("C");
Procedente de un fondo de C #, quiero crear un tipo de datos que defina una firma de función. En C #, este es un delegate
declarado así:
delegate void Greeter (string message);
public class Foo
{
public void SayHi (Greeter g) {
g("Hi!");
}
}
Ahora, quiero lograr algo similar en Typescript. Sé que Typescript no tiene tipos de delegados, sino solo lambdas. Se me ocurrió algo como esto:
class Foo {
SayHi (greeter: (msg: String) => void) {
greeter(''Hi!'');
}
}
Mientras esto funciona, quiero reutilizar la firma del método (msg:String) => void
par de veces y creo que sería más limpio crear un tipo personalizado, como el delegado en C #.
¿Alguna idea de cómo se puede hacer esto?
En TypeScript, las interfaces pueden tener firmas de llamada. En tu ejemplo, podrías declararlo así:
interface Greeter {
(message: string): void;
}
function sayHi(greeter: Greeter) {
greeter(''Hello!'');
}
sayHi((msg) => console.log(msg)); // msg is inferred as string
Puede crear algo así como un delegado como este:
type MyDelegate = (input: string) => void;
que define un nombre de tipo para un puntero de función, tal como lo hacen los delegados en C #. El siguiente ejemplo lo usa en combinación con parámetros genéricos de tipo:
type Predicate<T> = (item: T) => boolean;
export class List<T> extends Array<T> {
constructor(...items: T[]){
super();
for(let i of items || []){
this.push(i);
}
}
public hasAny(predicate?: Predicate<T>): boolean {
predicate = predicate || (i => true)
for(let item of this) {
if(predicate(item)) return true;
}
return false;
}
}
Tipo de definición para una expresión invocable (este es un borrador correcto, para humanos ... no es un BNF ni nada formal) :
callableType: (paramsDef) => returnType
paramsDef: MULTIPLE paramDef SEPARATED BY ,
paramDef: EITHER paramName: paramType
OR optionalParamName?: paramTypeWhenDefined
OR ...manyParamName: eachParamType[]
Ejemplo:
var func = something as ((...x: any[]) => any);
Entonces tú puedes:
var result = func("a", "b", 2);