Skip to content

Feature: method signature type operators #2365

@mindplay-dk

Description

@mindplay-dk

I sometimes find myself in need of a type operator that allows me to derive (anonymous) types from function signatures.

Please pay no attention to the syntax - the use of $ as operator here is an arbitrary choice, I'm not sure what this should look like.

The operator can be used to derive a new type from the return type of a given function type - for example, a function that dispatches a given function might have the same return type as the given function, but would have different arguments:

function dispatch<T extends Function>(func: T) {
    return func();
}

var test = dispatch(() => "Hello");

The return type (the type of test) in this example is any - but given the argument type { (): string }, with type inference, we actually should be able to infer the return type as string.

With an explicit return type for the function, we would need an operator that is capable of deriving a return type string from the type { (): string }, e.g. something like:

function dispatch<T extends Function>(func: T) : $T {
    return func();
}

The operator can also be used to derive a new type from the arguments of a given function type - for example:

function route<T extends Function>(func: T) : T$ {
   return <any> function() { ... }
}

var test = route((who: string) => console.log("Hello, " + who));

The return type of the function call in this case becomes { (who: string): void }.

The third use of this operator combines the argument list of one type with the return type of another type, e.g.:

interface Filter { (): boolean }

function accept<T extends Function>(filter: T) : T$Filter {
    return <any> function() { ... }
}

var test = accept((input: string) => true);

The return type of the function call in this case becomes { (input: string): boolean }, e.g. taking the argument list from the left operand, and the return type of the right operand.

In other words, this type operator combines the argument list from a left operand with the return type of a right operand - if the left operand is left out, it defaults to an empty argument list, or if the right operand is left out, it default to a void return type; that is, the default operand in either case essentially is Function e.g. { (): void }.

I believe this would enable us to construct some very elegant URL routers, MVC-style action filters, and probably other useful things.

One question I can't answer right now is, since this operator only operates on function signatures, what (if anything) happens to other members of the type? Perhaps it might work like the | operator and create a union type, or it might simply discard/ignore other members of both types.

I know this idea is sketchy and not a specification or a real proposal - for now I'm just putting the idea up here to see how you react to it :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions