3

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!

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

3 Comments

Whoa! That's great! Thank you very much! But why do you cast "_MyClass as any"?
@AlexanderCerutti because technically speaking it does not return the type MyClass declares it does. So we use a hammer to make it fit 😊
Oh, well... I understand now. I tried to remove it and saw. Typescript is weird sometimes. Again, thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.