Reputation: 398
I've created a generic class in Typescript to extend objects starting from one passed in the constructor (through a Proxy, which will be returned in the constructor).
class MyClass<T> {
private _a: 5;
constructor(source: T) {
...
return new Proxy(Object.assign(this, source), { ... });
}
}
If I want to instance MyClass
, I'll do:
interface DeepObject {
a: number,
b: {
c: number,
d: { ... }
}
}
const x = new MyClass<DeepObject>({
a: 1,
b: {
c: 2,
d: { ... }
}
});
So, as result, I will get x as a class that has inside "DeepObject" properties, like a
, b
, b.d
. But if I try to access to x.b.d
, it will obliviously not recognize the new properties as they get pushed inside in runtime at the current state.
Is there a way to use MyClass's T
parameter as a class return type, knowing that I'm returning an edited "this" (MyClass + new props)?
I tried to set it to the constructor but typescript doesn't let me, like
constructor(source: T): ThisType<MyClass<T>> & T { ... }
constructor(source: T): MyClass<T> & T { ... }
Moreover, using //@ts-ignore
in multiple lines (like
//@ts-ignore
x.b.c = 5;
//@ts-ignore
x.b.d.f = 9;
), is a misusage of typescript features, IMHO.
The same is to put [key: string]: any
inside the class, above or below the properties.
Thank you very much!
Upvotes: 3
Views: 806
Reputation: 249466
You can't directly charge the return type of the constructor. You can however use the same approach as Proxy
usses and have a separate declaration for the constructor which does use the generic type parameter in the return
class _MyClass<T> {
private _a: 5;
constructor(source: T) {
return new Proxy(Object.assign(this, source), { ... });
}
}
interface DeepObject {
a: number,
b: {
c: number,
d: { }
}
}
const MyClass : {
new<T> (s:T) : _MyClass<T> & T
} = _MyClass as any
const x = new MyClass<DeepObject>({
a: 1,
b: {
c: 2,
d: { }
}
});
x.b.c
Upvotes: 1