Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: method signature type operators #2365

Closed
mindplay-dk opened this issue Mar 15, 2015 · 1 comment
Closed

Feature: method signature type operators #2365

mindplay-dk opened this issue Mar 15, 2015 · 1 comment
Labels
Duplicate An existing issue was already created Suggestion An idea for TypeScript

Comments

@mindplay-dk
Copy link

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 :-)

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Needs More Info The issue still hasn't been fully clarified labels Apr 20, 2015
@mhegazy
Copy link
Contributor

mhegazy commented Feb 20, 2016

closing in favor of #6606

@mhegazy mhegazy closed this as completed Feb 20, 2016
@mhegazy mhegazy added Duplicate An existing issue was already created and removed Needs More Info The issue still hasn't been fully clarified labels Feb 20, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants