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

Suggestion: implicitly infer parameter types for the implementation signature of an overloaded method #7763

Closed
malibuzios opened this issue Apr 1, 2016 · 3 comments
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds

Comments

@malibuzios
Copy link

The current pattern for method overloading in a class is:

class Example {
    // Overload signatures:
    func(param1: number, param2: string): number;
    func(param1: number[], param2: boolean[]): number[];

    // Actual method implementation:
    func(param1: number | number[], param2: string |  boolean[]): number | number[] {
        ...
    }
}

However the implementation signature is only in practice beneficial for parameter references within the body of the function. E.g., even if the parameter types of the implementation signature were, say, all set to any:

func(param1: any, param2: any): any {
  ...
}

A caller is still bound by the overload signatures:

let example = new Example();
example.func("ABC", 123); // Error! no overload of 'func' matches the arguments

Suggestion:

The parameter and return type of the implementation signature could be implicitly inferred if they are not given an explicit type:

class Example {
    func(param1: number, param2: string): number;
    func(param1: number[], param2: boolean[]): number[];

    func(param1, param2) {
        let x = param1; // type of x is number | number[]
        let y = param2; // type of y is string | boolean[]

        return "ABC"; // Error: return type has been implicitly inferred to number | number[] 
    }
}

Having this would make it less cumbersome to define and maintain overloaded methods.

Has this ever been discussed before? and if so, what were the arguments against it?

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Apr 1, 2016
@RyanCavanaugh
Copy link
Member

Strangely I don't think anyone's ever proposed this. It makes a lot of sense.

Just to write out the rules:

  • Each parameter has the type of the union formed by its corresponding parameters by position
  • If a signature is "too short", the parameter appears as optional (this matters for --strictNullChecks or whatever we call that flag)
  • A signature with a rest arg appears as having infinitely many optional parameters
  • Return type is inferred by the union of the return type signatures.

@DanielRosenwasser
Copy link
Member

That's a good idea, given that it's what most people end up writing today.

The downside of that is that you're still stuck with a union of every member, so you'd need to continue casting or doing type checks, whereas usually in JavaScript you discriminate your overloads based on some of the arguments you were given. Ideally, we'd be able to actually tie the uses of a variable to its potential overload as well.

For instance, if I had

function drawLine(startX: number, startY: number, endX: number, endY: number): void;
function drawLine(start: { x: number; y: number }, end: { x: number; y: number }): void;
function drawLine(a, b, c, d) {
    if (typeof a === "number") {
        // 'a', 'b', 'c', and 'd' have type 'number' here.
    }
    else {
        // 'a' and 'b' have type '{ x: number; y: number }.
        // 'c' and 'd have type 'undefined'.
    }
}

@RyanCavanaugh RyanCavanaugh added the Revisit An issue worth coming back to label Apr 20, 2016
@RyanCavanaugh
Copy link
Member

Concern from the slog was that this could potentially introduce some very unwieldy types by default. Implementors may prefer any when their signatures are complex (though this is an easy type annotation to add)

@RyanCavanaugh RyanCavanaugh added Too Complex An issue which adding support for may be too complex for the value it adds and removed In Discussion Not yet reached consensus Revisit An issue worth coming back to labels Apr 3, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Suggestion An idea for TypeScript Too Complex An issue which adding support for may be too complex for the value it adds
Projects
None yet
Development

No branches or pull requests

3 participants