Declare a delegate type in Typescript

前端 未结 5 679
走了就别回头了
走了就别回头了 2021-01-30 10:12

Coming from a C# background, I want to create a datatype that defines a function signature. In C#, this is a delegate declared like this:

delegate v         


        
相关标签:
5条回答
  • 2021-01-30 10:43

    You can create something like a delegate by using a type alias:

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

    which defines a type name for a function pointer, just as delegates do in C#. The following example uses it in combination with generic type parameters:

    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;
        }
    }
    
    0 讨论(0)
  • 2021-01-30 10:43

    Five years and many, many TS versions later I find myself using a simpler type definition for declaring function types:

    type Greeter = (msg: string) => void;
    const someGreeter: Greeter = (msg: string) => `Hi there with ${msg}`;
    
    0 讨论(0)
  • 2021-01-30 10:43

    Type definition for a callable expression (this is a draft ok, for humans... not a BNF or anything formal):

    callableType: (paramsDef) => returnType
    
    paramsDef:    MULTIPLE paramDef SEPARATED BY ,
    
    paramDef:     EITHER   paramName: paramType
                      OR   optionalParamName?: paramTypeWhenDefined
                      OR   ...manyParamName: eachParamType[]
    

    Example:

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

    Then you can:

    var result = func("a", "b", 2);
    
    0 讨论(0)
  • 2021-01-30 10:48

    In TypeScript, interfaces can have call signatures. In your example, you could declare it like this:

    interface Greeter {
        (message: string): void;
    }
    
    function sayHi(greeter: Greeter) {
        greeter('Hello!');
    }
    
    sayHi((msg) => console.log(msg)); // msg is inferred as string
    
    0 讨论(0)
  • 2021-01-30 11:06

    I now publish and use @steelbreeze/delegate; it has a few limitations compared to the C# delegate, in that it's immutable, but otherwise works well (and when called returns results from all the functions called).

    It lets you write code such as:

    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 讨论(0)
提交回复
热议问题