在Typescript中声明委托类型

Dyn*_*lon 54 c# lambda delegates types typescript

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

delegate void Greeter (string message);

public class Foo
{
    public void SayHi (Greeter g) {
        g("Hi!");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想在Typescript中实现类似的功能.我知道Typescript没有委托类型,但只有lambdas.我提出了这样的事情:

class Foo {
    SayHi (greeter: (msg: String) => void) {
        greeter('Hi!');
    }
}
Run Code Online (Sandbox Code Playgroud)

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

有什么想法可以做到这一点?

Rya*_*ugh 68

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

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

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

sayHi((msg) => console.log(msg)); // msg is inferred as string
Run Code Online (Sandbox Code Playgroud)

  • 例如`function foo(x:(n:number)=> string){console.log(x(3)); }`,或等效`function foo(x:{(n:number):string;}){...}` (9认同)

Orp*_*hid 31

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考:这些被称为*类型别名*. (3认同)

Dyn*_*lon 8

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

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

  • 请注意,第 2 行中的 `: string` 不是必需的;可以根据分配给“Greeter”来推断类型。 (2认同)