Skip to content
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

Improving typing for getPrototypeListOf #17

Open
AbdealiLoKo opened this issue Jan 6, 2023 · 1 comment
Open

Improving typing for getPrototypeListOf #17

AbdealiLoKo opened this issue Jan 6, 2023 · 1 comment

Comments

@AbdealiLoKo
Copy link

AbdealiLoKo commented Jan 6, 2023

I was using super.class(BaseClass) in may cases and it handles typing correctly.
I see: protected class<U extends T>(type: U): U; in the .d.ts file

I was trying out getPrototypeListOf and realized that I was getting all the baseClass as any
And I saw: export function getPrototypeListOf(o: any): any[]; in the .d.ts file
So, creating this issue to potentially improve the typing here to get more accurate types

PS: I have no idea if it is possible at all :)

I did try this:

export class ChildClass extends classes(BaseClass1, BaseClass2) {
    myFunc() {
        (getPrototypeListOf(ChildClass) as (BaseClass1 | BaseClass2)[]).forEach(baseClass => {
            baseClass.myFunc()
        })
    }
}

NOTE: This will assume baseClass has the type (typeof BaseClass1 | typeof BaseClass2)
So, if all my base classes implement a particular function - then this work out quite well

Doing: getPrototypeListOf(ChildClass) as [BaseClass1, BaseClass2] would also work and be more accurate

@fasttime
Copy link
Owner

fasttime commented Jan 6, 2023

Yes this would be helpful in many cases, but I would not want to change the type definition of getPrototypeListOf for this.
The current typing is intended to keep getPrototypeListOf consistent with Object.getPrototypeOf, which returns any.
Crucially, Object.getPrototypeOf and its counterpart Object.setPrototypeOf are inherently not type-safe, because they are intended to work with objects whose type changes dynamically or is not known at compile time (like setting the prototype or getting the prototype to access its properties).
But there could certainly be separate helper types and functions to handle what is not trivial using the core functionality.

In the case you show, since the list of base classes is known in advance, one could even rewrite the code without getPrototypeListOf like this:

const baseClasses = [BaseClass1, BaseClass2];
export class ChildClass extends classes(...baseClasses) {
    myFunc() {
        baseClasses.forEach(baseClass => {
            baseClass.prototype.myFunc();
        })
    }
}

(Note that what is named baseClass in your for-each is actually a prototype)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants