i want to extend the Object prototype by adding a method that returns a proxified version of any object
Object.defineProperty(Object.prototype, 'proxify, {
get: function(this: any) {
// creating a proxy for the darn object
}
});
const data = {
name: 'hey',
value: 123
};
const proxy = data.proxify();
declare global {
interface Object {
proxify(): {
[P in keyof this]: Proxied<this [p]>; // expected to work, actual: A 'this' type is available only in a non-static member of a class or interface.
}
}
}
what am i doing wrong?
What are the definitions of T and Proxied?
The following works but may not be what you are trying to accomplish
Object.defineProperty(Object.prototype, 'proxify', {
get: function (this: any) {
// creating a proxy for the darn object
}
});
const data = {
name: 'hey',
value: 123
};
const proxy = data.proxify();
declare global {
interface Object {
proxify(): {
[P in keyof this]: Proxied<this[P]>;
};
}
}
export type Proxied<T> = {
[P in keyof T]: Proxied<T[P]>;
};
For the sake of argument, isn't a proxy supposed to be transparent? 馃槢
it doesnt really matter what Proxified is, because it breakes at this in [P in keyof this]
dont remember anythhing about them having to look exactly like the original objects (although it wont hurt if they do)
afaict, the only thing proxy should do to be standing between your object and you
T should be read this, fixed
I was being somewhat facetious. Seriously though it does appear that mapping this works correctly.
haven't you seen 'this' type is available only in a non-static member of a class or interface anywhere?
I've seen it a number of times but only in type aliases and other contexts where this would not be available.
declare global {
interface Object {
proxify(): {
[P in keyof this]: Proxied<this[P]>;
};
}
}
Doesn't give me that error.
say Proxified <T> = T what can you see wgen you type data.proxify ().? (whar does autocomplete suggest?)
This is what I see

which is definitely not what we want here.
Update
It seems that mapping the type of this loses properties added via refinements and annotations. In order to have name and value expanded into the mapping I ended up with
interface Object {
proxify<T>(this: T): {
[P in keyof T]: Proxied<T[P]>
};
}
Which works but obviously doesn't map this.
This is probably the same problem as https://github.com/Microsoft/TypeScript/issues/12349
and is not supported for now because of performance(I guess), reference https://github.com/Microsoft/TypeScript/pull/11929#issuecomment-261744874
@HerringtonDarkholme Thanks for providing the clarifying context, it is very helpful. I had totally forgotten that you had already raised an issue requesting this behavior, and I didn't realize the implications, or consider this the same issue.
In #12349, you state the specific problem concisely in the first sentence
it seems this type is resolved too eagerly in parent class.
I suggest we move any further discussion (back) into #12349.
This is not the same as #12349. these are two different issues. the thing is internally, all objects get the apparent members of Object, but it is not that they extend object. there is no distinction if there are no this types, but it breaks if this types are defined on Object since these signatures or properties will not be instantiated with the type of the object you are using.
and yes, the concern is performance. since augmenting Object is not that common scenario.
Most helpful comment
This is probably the same problem as https://github.com/Microsoft/TypeScript/issues/12349
and is not supported for now because of performance(I guess), reference https://github.com/Microsoft/TypeScript/pull/11929#issuecomment-261744874