Skip to content

Typing function factory taking dynamic class types varying constructor arguments. #7936

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

Closed
prasannavl opened this issue Apr 7, 2016 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@prasannavl
Copy link

Simply put, I'm trying to achieve a mixin like functionality.
The pattern I'm using is this:

Breaking it down into javascript:

const Factory = function factory(X) {
    return class extends X implements IService {
        private _service: IService;
        constructor(service: IService) {
            super(service);
            this._service= service;
        }
    }
}

Typing it in typescript I ended up with this:

const Factory = function factory<T>(X: (FunctionConstructor & (new(service: IService<T>) => any))) {
    return class extends X<T> implements IService<T> {
        private _service: IService<string>;
        constructor(service: IService<string>) {
            super(service);
            this._service= service;
        }
    }
}

But I'm still unable to get it to work. FunctionConstructor seems to do the trick the if constructor has no arguments. Even using any doesn't help. Is there a way to achieve this? Or is this a bug?

@mhegazy
Copy link
Contributor

mhegazy commented Apr 26, 2016

the issue here is that you can not extend a generic type parameter. this is tracked by #2225.

if i am not wrong, you want to define factory as:

const Factory = function factory<T>(X: { new (): T }) {
    return class extends X {

    }
}

@mhegazy
Copy link
Contributor

mhegazy commented Apr 26, 2016

having said that, you can work around this by casting to any at the extend point, and casting to the intersection type at the output:

interface IService<T> {
    service: T;
}
class MyClass { o: any }

const Factory = function factory<T>(X: { new (): T }): { new (): (T & IService<T>) } {
    var base: { new (): Object } = X;
    var C = class extends base implements IService<T> {
        service: T
    };
    return <any>C;
}


var x = new (Factory(MyClass))();
x.o;
x.service; // IService<MyClass>

@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 26, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Apr 26, 2016

closing in favor of #2225

@mhegazy mhegazy closed this as completed Apr 26, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants