type overload c# types lambda delegates typescript

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);