Hi,
I'm puzzled by the interaction between Promises and Proxy objects.
I'm trying the run the following code:
const prom = new Promise( (res, rej) => res( 34 ) );
const xprom = new Proxy( prom, {} );
Promise.prototype.then.call( xprom, val => console.log( val ) );
It fails with the error message:
proxy.js:5
Promise.prototype.then.call( xprom, val => console.log( val ) );
^
TypeError: Method Promise.prototype.then called on incompatible receiver [object Object]
at Proxy.then (<anonymous>)
at Object.<anonymous> (proxy.js:5:24)
at Module._compile (node:internal/modules/cjs/loader:1108:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
at Module.load (node:internal/modules/cjs/loader:973:32)
at Function.Module._load (node:internal/modules/cjs/loader:813:14)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
at node:internal/main/run_main_module:17:47
If I understand correctly, this is conform to the ECMASpefication that
defines Promise.prototype.then as:
27.2.5.4 Promise.prototype.then ( onFulfilled, onRejected )
When the then method is called with arguments onFulfilled and onRejected, the following steps are taken:
1. Let promise be the this value.
2. If IsPromise(promise) is false, throw a TypeError exception.
and isPromise is defined as :
27.2.1.6 IsPromise ( x )
The abstract operation IsPromise takes argument x. It checks for the promise brand on an object. It performs the following steps when called:
1. If Type(x) is not Object, return false.
2. If x does not have a [[PromiseState]] internal slot, return false.
3. Return true.
I'm not quite sure about the [[PromiseState]] but my guess is that
this designates only "builtin" Promise objects.
The problem I see with 27.2.1.6, is that it creates a means a program
may use to distinguish plain values from proxies values. I though that
the whole Proxy design was intended to make this impossible. My
question is then the following:
Is there a reason for which Promise.prototype.then (and all the
other Promise.protype methods) must behave differently for promises and
proxy objects or could Promise.prototype.then be modified so that it is
also able to handle proxy objects?
The reason for that question is the following. We are trying to build
a tool for debugging Typecript programs. Our idea is to map TypeScript
types to higher-order contracts and to execute them with dynamic
verification. These higher-order contracts are implemented with
proxies. So far, we are able to cope with all the TypeScript
constructs but promises because of the aformentionned problem.
I thank you in advance for your help or explanations.