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

mapped intersection loses type information #30545

Closed
kolodny opened this issue Mar 22, 2019 · 1 comment
Closed

mapped intersection loses type information #30545

kolodny opened this issue Mar 22, 2019 · 1 comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@kolodny
Copy link

kolodny commented Mar 22, 2019

TypeScript Version: 3.4.0-dev.201xxxxx

Search Terms:
"mapped types", "overload", "intersection"

Code

type ReturnObjects<T> = {
    [K in keyof T]: T[K] extends ((...args: any[]) => any) ?
    T[K] & Returnable<T[K]> :
    never
}

type Returnable<Fun extends (...args: any[]) => any> = {
    returnValue(val: ReturnType<Fun>): void;
}

interface I {
    f(): string;
    f(x: any): number;
}

let argsObj: ReturnObjects<I>;
argsObj.f.returnValue(1) // OK
argsObj.f.returnValue('1') // ERROR?!```

Expected behavior:

argsObj.f.returnValue('1') should not cause a type error

Actual behavior:

argsObj.f.returnValue('1') causes a type error

Playground Link

Related Issues: Couldn't find anything

Note that if I switch the order of the interface, it will only expect the other overload. I believe that typescript is overriding the previous value and not intersecting them

@kolodny kolodny changed the title Intersection mapped mapped intersection loses type information Mar 22, 2019
@jack-williams
Copy link
Collaborator

jack-williams commented Mar 22, 2019

The problem here is that interface I contains an overloaded function that is passed to ReturnType. When inferring the return type only the last overload is chosen, as specified here #21496:

When inferring from a type with multiple call signatures (such as the type of an overloaded function), inferences are made from the last signature (which, presumably, is the most permissive catch-all case). It is not possible to perform overload resolution based on a list of argument types (this would require us to support typeof for arbitrary expressions, as suggested in #6606, or something similar).

This is why the number input is ok but the string input is not, and this explains the behaviour you describe here:

Note that if I switch the order of the interface, it will only expect the other overload.

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Mar 26, 2019
@kolodny kolodny closed this as completed Mar 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants