Skip to content

fix(#20846 lib/es2015): override new Proxy<T, U> #44458

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

Conversation

IgorNovozhilov
Copy link
Contributor

Fixes #20846

Faced with the need to definition type the Proxy output in my project, I got acquainted with the problem #20846.
I suggest the following solution using overloads, preserving the health of the current behavior and backward compatibility with the current definition format

example:

interface XProxyConstructor {
  revocable<T extends object>(target: T, handler: XProxyHandler<T, any>): { proxy: T; revoke: () => void; };
  revocable<T extends object, U extends object>(target: T, handler: XProxyHandler<T, U>): { proxy: U; revoke: () => void; };
  new <T extends object>(target: T, handler: XProxyHandler<T, any>): T;
  new <T extends object, U extends object>(target: T, handler: XProxyHandler<T, U>): U;
}
declare var XProxy: XProxyConstructor;


interface A { a: string }
interface B { b: number }

const a: A = { a: '' }

var b = new XProxy<A, B>(a, {})

in VSCode

Снимок экрана от 2021-06-06 13-55-37

Снимок экрана от 2021-06-06 13-57-44

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Jun 6, 2021
@IgorNovozhilov IgorNovozhilov marked this pull request as ready for review June 6, 2021 11:33
@sandersn sandersn requested review from orta and rbuckton June 18, 2021 23:07
@dominikdosoudil
Copy link

@IgorNovozhilov interface B states that proxy instance has member b but it will be undefined since you are not implementing get method in proxy handler imho. Isn't that right? I think that handler implementation should be checked somehow too.

@IgorNovozhilov
Copy link
Contributor Author

@dominikdosoudil
Copy link

@IgorNovozhilov Yeah, get is optional. That's the problem. You are showing that b.b is number in the first screenshot. However it will be undefined since get is not provided.

interface A { a: string }
interface B { b: number }

const a: A = { a: '' }

var b = new XProxy<A, B>(a, {})

b.b // undefined because 'get' not provided in handler however your typing says it will be number

@orta
Copy link
Contributor

orta commented Aug 4, 2021

I'm pretty hesitant on this PR, because every time we've introduced extra generics like this into the stdlib a lot of things break unexpectedly. Let's see what happens with the larger test suites.

@typescript-bot test this
@typescript-bot run dt
@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 4, 2021

Heya @orta, I've started to run the parallelized Definitely Typed test suite on this PR at 5510089. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 4, 2021

Heya @orta, I've started to run the extended test suite on this PR at 5510089. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 4, 2021

Heya @orta, I've started to run the parallelized community code test suite on this PR at 5510089. You can monitor the build here.

@dominikdosoudil
Copy link

@orta Members (and their types) of Proxy depend on its constructor arguments so it cannot have other than generic typing.(any should not be used) So replacing the any type of get arguments is basically the correct way.

However I've shown the bug that brings this PR so I think that there is no point in running tests because if they pass, there is still obvious issue.

@typescript-bot
Copy link
Collaborator

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@sandersn sandersn requested review from gabritto and removed request for orta February 24, 2022 22:12
@sandersn sandersn assigned gabritto and unassigned orta Feb 24, 2022
Copy link
Member

@gabritto gabritto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need more tests to be able to reason about how that change would work. If you could add the tests I mentioned in comments, that would be a great start. Thanks.

apply?(target: T, thisArg: any, argArray: any[]): any;
construct?(target: T, argArray: any[], newTarget: Function): object;
defineProperty?(target: T, p: string | symbol, attributes: PropertyDescriptor): boolean;
deleteProperty?(target: T, p: string | symbol): boolean;
get?(target: T, p: string | symbol, receiver: any): any;
get?<K extends keyof U>(target: T, p: K, receiver: U): U[K];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a test for the program in the original bug? (#20846)
I don't understand how inference of U would work to fix the bug for that program, since in that case there is no receiver.

new <T extends object>(target: T, handler: ProxyHandler<T>): T;
revocable<T extends object>(target: T, handler: ProxyHandler<T, any>): { proxy: T; revoke: () => void; };
revocable<T extends object, U extends object>(target: T, handler: ProxyHandler<T, U>): { proxy: U; revoke: () => void; };
new <T extends object>(target: T, handler: ProxyHandler<T, any>): T;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't immediately see how this ordering of overloads would work. Could you add tests where TypeScript choses one vs the other overload signatures?

@gabritto
Copy link
Member

gabritto commented Mar 8, 2022

For future reference: if we want to move on with this PR, we should test this with vue and jsdom, which seem to be the only big users of Proxy.

@sandersn
Copy link
Member

sandersn commented Jun 1, 2022

@IgorNovozhilov Do you want to keep working on this? Otherwise I'd like to close it to reduce the number of open PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Typescript can't infer types when using Proxy
6 participants