Skip to content

Extend generic static bug #17829

Closed
Closed

Description

@mushishi78

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.

Activity

  1. changed the title [-]Extend Generic static bug[/-] [+]Extend generic static bug[/+] on Aug 16, 2017
  2. ahejlsberg commented on Aug 16, 2017

    @ahejlsberg
    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
  3. markboyall commented on Aug 17, 2017

    @markboyall

    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.

  4. ahejlsberg commented on Aug 17, 2017

    @ahejlsberg
    Member

    Mark Boyall (@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).

  5. locked and limited conversation to collaborators on Jun 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Breaking ChangeWould introduce errors in existing codeBugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions