Skip to content

Intersection type from Function and object literal type doesn't work #22877

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

Closed
cshaa opened this issue Mar 26, 2018 · 5 comments
Closed

Intersection type from Function and object literal type doesn't work #22877

cshaa opened this issue Mar 26, 2018 · 5 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@cshaa
Copy link

cshaa commented Mar 26, 2018

TypeScript Version: 2.7.2

Search Terms: Function interface, object literal type, intersection, type alias

Code

type MyConstructorType = Function & {prototype: {foo: number}};
let bar = (function () { }) as MyConstructorType;
bar.prototype.foo();

or equivalent:

let bar = (function () { }) as Function & {prototype: {foo: number}};
bar.prototype.foo();

doesn't even depend on the order

let bar = (function () { }) as {prototype: {foo: number}} & Function;
bar.prototype.foo();

Expected behavior:
The function call bar.prototype.foo() should throw a compile time error, as foo is marked as a number.

Actual behavior:
The property bar.prototype is of type any, no matter the intersection type.

Playground Link: here

Related Issues: #17757

@ghost
Copy link

ghost commented Mar 26, 2018

The problem is that Function.prototype is any, and intersecting with any doesn't narrow the type:

declare const x: { a: any } & { a: string };
x.a;

Unfortunately, I don't know a way to write a callable/constructable type that doesn't automatically get prototype: any added to it.

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Mar 26, 2018
@RyanCavanaugh
Copy link
Member

Would need subtraction types or spread types to represent this pattern

@cshaa
Copy link
Author

cshaa commented Mar 27, 2018

Ah, my bad, evidently I didn't read the docs properly. However it still seems pretty counter-intuitive and broken to me 🤔. From my (probably naïve) point of view, any is the widest type and the intersection of any and an arbitrary type A should always be A. What is the rationale behind the actual implementation? Why doesn't it obey the intuitive set-theory rules?

@ghost
Copy link

ghost commented Mar 27, 2018

any isn't just a top type, it's an unsafe top/bottom type. const x: any = 0; and const y: string = x both work -- everything is assignable to any and any is assignable to everything.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants