Zadeklaruj typ delegata w Typescript

PochodzÄ ... c z tĹ ' A C#, chcÄ ™ stworzyÄ ‡ typ danych, ktĂłry definiuje sygnaturÄ ™ funkcji. W C# jest to delegate zadeklarowane Tak:

delegate void Greeter (string message);

public class Foo
{
    public void SayHi (Greeter g) {
        g("Hi!");
    }
}

Teraz chcę osiągnąć podobne w maszynopisie. Wiem, że Typescript nie ma typów delegatów, ale tylko lambda. Wymyśliłem coś takiego:

class Foo {
    SayHi (greeter: (msg: String) => void) {
        greeter('Hi!');
    }
}

Podczas gdy to działa, chcę ponownie użyć podpisu metody (msg:String) => void kilka razy i myślę, że czystszym byłoby utworzenie niestandardowego typu-takiego jak delegat w C#.

Any pomysły, jak można to zrobić?

Author: Dynalon, 2013-12-01

4 answers

W maszynopisie interfejsy mogą mieć sygnatury wywołania. W twoim przykładzie możesz zadeklarować to w następujący sposób:

interface Greeter {
    (message: string): void;
}

function sayHi(greeter: Greeter) {
    greeter('Hello!');
}

sayHi((msg) => console.log(msg)); // msg is inferred as string
 55
Author: Ryan Cavanaugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-01 08:46:33

Możesz utworzyć coś takiego jak delegat:

type MyDelegate = (input: string) => void;

Który definiuje nazwę typu wskaźnika funkcji, tak jak to robią delegaci w C#. Poniższy przykład używa go w połączeniu z parametrami typu ogólnego:

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;
    }
}
 17
Author: Orphid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-10 17:54:32

Type definition for a calable expression (jest to szkic ok, dla ludzi... ani BNF ani nic formalnego):

callableType: (paramsDef) => returnType

paramsDef:    MULTIPLE paramDef SEPARATED BY ,

paramDef:     EITHER   paramName: paramType
                  OR   optionalParamName?: paramTypeWhenDefined
                  OR   ...manyParamName: eachParamType[]

Przykład:

var func = something as ((...x: any[]) => any);

Wtedy możesz:

var result = func("a", "b", 2);
 2
Author: Miguel Angelo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 11:11:32

Teraz publikuję i używam @ steelbreeze / delegate ; ma kilka ograniczeń w porównaniu do delegata C#, w tym, że jest niezmienny, ale poza tym działa dobrze (a gdy wywołane zwraca wyniki ze wszystkich wywołanych funkcji).

Pozwala na pisanie kodu takiego jak:

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");
 0
Author: Mesmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-09 08:51:06