首页 文章

在Typescript中声明委托类型

提问于
浏览
45

来自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 回答

  • 59

    在TypeScript中,接口可以具有呼叫签名 . 在您的示例中,您可以将其声明为:

    interface Greeter {
        (message: string): void;
    }
    
    function sayHi(greeter: Greeter) {
        greeter('Hello!');
    }
    
    sayHi((msg) => console.log(msg)); // msg is inferred as string
    
  • 2

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

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

    可调用表达式的类型定义(这是一个草稿ok,对于人类......不是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);
    
  • 0

    五年以及许多TS版本后来我发现自己使用更简单的 type 定义来声明函数类型:

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

    我现在发布并使用@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");
    

相关问题