在Typescript中声明委托类型

时间:2013-12-01 08:44:22

标签: c# types lambda delegates typescript

来自C#背景,我想创建一个定义函数签名的数据类型。在C#中,这是delegate声明如下:

delegate void Greeter (string message);

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

现在,我想在Typescript中实现类似的功能。我知道Typescript没有委托类型,但只有lambdas。我想出了类似的东西:

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

虽然这有效,但我想重复使用方法签名(msg:String) => void几次,并认为创建自定义类型会更简洁 - 就像C#中的委托一样。

任何想法如何做到这一点?

5 个答案:

答案 0 :(得分:60)

在TypeScript中,接口可以有呼叫签名。在您的示例中,您可以这样声明:

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

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

sayHi((msg) => console.log(msg)); // msg is inferred as string

答案 1 :(得分:24)

您可以创建像这样的委托:

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

定义函数指针的类型名称,就像委托在C#中一样。以下示例将其与泛型类型参数结合使用:

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

答案 2 :(得分:1)

可调用表达式的类型定义(对于人类而言,这是一个好的草稿......不是BNF或任何正式的)

callableType: (paramsDef) => returnType

paramsDef:    MULTIPLE paramDef SEPARATED BY ,

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

示例:

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

然后你可以:

var result = func("a", "b", 2);

答案 3 :(得分:1)

五年后,许多TS版本后来发现我使用了一个更简单的type定义来声明函数类型:

type Greeter = (msg: string) => void;
const someGreeter: Greeter = (msg: string) => `Hi there with ${msg}`;

答案 4 :(得分:0)

我现在发布并使用@steelbreeze/delegate;与C#委托相比,它有一些限制,因为它是不可变的,但在其他方面效果很好(并且当被调用时会返回所有被调用函数的结果)。

它允许您编写如下代码:

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