Repository: TypeScript
Issue: Suggestion: Automatically infer argument types in overloaded function implementation
Labels: Suggestion,Awaiting More Feedback

## Search Terms

infer, arguments, function, overload

## Suggestion

For basic container types (Point, Size, Rect, ...) I often write constructors and methods with overloaded signatures so they can be called with the container type itself or with the separate components of the container as arguments. Example:

```typescript
class Point {
    constructor(point: Point);
    constructor(x: number, y: number);
    constructor(arg1: Point | number, arg2?: number) {
        if (arg1 instanceof Point) {
            this.x = arg1.getX();
            this.y = arg1.getY();
        } else {
            this.x = arg1;
            this.y = arg2!;
        }
    }
}
```

And I always wonder why I have to specify the argument types in the implementation again when I already defined the possible types in the overload signatures. 

In this simple `Point` type it is still pretty easy but imagine a `Rect` type which can work with four number arguments, two `Point` arguments, a `Point` and `Size` argument or a `Rect` argument. Manually writing the combined signature for all these overloaded signatures is cumbersome. And I don't want to use `any` here because I want type checking in the function body.

An alternative way to write this example is this:

```typescript
class Point {
    constructor(point: Point);
    constructor(x: number, y: number);
    constructor(...args: [ Point ] | [ number, number ]) {
        const [ arg1, arg2 ] = args;
        // arg1 is now Point | number
        // arg2 is now number | undefined (At least since TS 3.2 because of #27543)
        ...
    }
}
```

This shows how easy it should be for TypeScript to collect the possible function signatures into a union type so writing `constructor(...args)` would be enough.

Taking this a step further I even like to write this so I don't need to destructure the arguments myself:

```typescript
class Point {
    constructor(point: Point);
    constructor(x: number, y: number);
    constructor(arg1, arg2) {
        // arg1 is now Point | number
        // arg2 is now number | undefined
        ...
    }
}
```

Taking this ANOTHER step further TypeScript could even narrow down the inferred function signatures by each type check done within the function body:

```typescript
class Point {
    constructor(point: Point);
    constructor(x: number, y: number);
    constructor(arg1, arg2) {
        if (arg1 instanceof Point) {
            // arg2 can now only be `undefined` because the instanceof check removes 
            // the second call signature (where arg1 is a number) from the list of possible 
            // call signatures
            this.x = arg1.getX();
            this.y = arg1.getY();
        } else {
            // arg2 can now only be `number` because the failed instanceof check removes 
            // the first call signature from the list of possible signatures
            this.x = arg1;
            this.y = arg2;
        }
    }
}
```

I guess the type narrowing is harder to implement but at least the automatic type inference of each argument shouldn't be that hard. So it would be very nice if a future version of TypeScript could do this so using overloading gets a bit easier.


## Checklist

My suggestion meets these guidelines:
* [X] This wouldn't be a breaking change in existing TypeScript / JavaScript code
* [X] This wouldn't change the runtime behavior of existing JavaScript code
* [X] This could be implemented without emitting different JS based on the types of the expressions
* [X] This isn't a runtime feature (e.g. new expression-level syntax)