Skip to content

Extend generic static bug #17829

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
mushishi78 opened this issue Aug 16, 2017 · 3 comments
Closed

Extend generic static bug #17829

mushishi78 opened this issue Aug 16, 2017 · 3 comments
Assignees
Labels
Breaking Change Would introduce errors in existing code Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@mushishi78
Copy link

TypeScript Version: 2.4.0

Code

function base<T>() {
    class Base {
        static prop: T;
    }
    return Base;
}

class Gen<T> extends base<T>() {}
class Spec extends Gen<string> {}

<string>Spec.prop;

Expected behavior: Either the static property prop is of type string or I'm given an error to prevent this happening earlier with clear error message.

Actual behavior: It claims that prop is of type T.

@mushishi78 mushishi78 changed the title Extend Generic static bug Extend generic static bug Aug 16, 2017
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Aug 16, 2017
@ahejlsberg
Copy link
Member

The issue here is that type parameters introduced by a class declaration should not be in scope within the expression part of the base class heritage clause. However, when a type argument list follows the expression part, they should be in scope there. So, this should be an error

class Gen<T> extends base<T>() {}  // Error, T not in scope in base class expression

@ahejlsberg ahejlsberg self-assigned this Aug 16, 2017
@mhegazy mhegazy added this to the TypeScript 2.6 milestone Aug 16, 2017
@markboyall
Copy link

markboyall commented Aug 17, 2017

Then... how would you implement the Gen class above? Or would it need to be wrapped as well?

I'm not even sure what the lifetime of the static inside the base class is, whether it's one per call of base, or just one.

@ahejlsberg
Copy link
Member

@markboyall Yes, you'd need to wrap the derived class in a function as well such that you can pass a type parameter that differs per invocation. For example:

function base<T>() {
    class Base {
        static prop: T;
    }
    return Base;
}

function derived<T>() {
    class Derived extends base<T>() {
        static anotherProp: T;
    }
    return Derived;
}

class Spec extends derived<string>() {}

Spec.prop;  // string
Spec.anotherProp;  // string

The lifetime of the statics above is one per invocation of their containing function. Effectively, a class declaration manufactures a class constructor function each time it is executed (which is only once for a global class, but can be many times for a class nested in a function).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Breaking Change Would introduce errors in existing code Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

5 participants