question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Polymorphic "this" for static members

See original GitHub issue

When trying to implement a fairly basic, but polymorphic, active record style model system we run into issues with the type system not respecting this when used in conjunction with a constructor or template/generic.

I’ve posted before about this here, #5493, and #5492 appears to mention this behavior also.

And here is an SO post this that I made: http://stackoverflow.com/questions/33443793/create-a-generic-factory-in-typescript-unsolved

I have recycled my example from #5493 into this ticket for further discussion. I wanted an open ticket representing the desire for such a thing and for discussion but the other two are closed.

Here is an example that outlines a model Factory which produces models. If you want to customize the BaseModel that comes back from the Factory you should be able to override it. However this fails because this cannot be used in a static member.

// Typically in a library
export interface InstanceConstructor<T extends BaseModel> {
    new(fac: Factory<T>): T;
}

export class Factory<T extends BaseModel> {
    constructor(private cls: InstanceConstructor<T>) {}

    get() {
        return new this.cls(this);
    }
}

export class BaseModel {
    // NOTE: Does not work....
    constructor(private fac: Factory<this>) {}

    refresh() {
        // get returns a new instance, but it should be of
        // type Model, not BaseModel.
        return this.fac.get();
    }
}

// Application Code
export class Model extends BaseModel {
    do() {
        return true;
    }
}

// Kinda sucks that Factory cannot infer the "Model" type
let f = new Factory<Model>(Model);
let a = f.get();

// b is inferred as any here.
let b = a.refresh();

Maybe this issue is silly and there is an easy workaround. I welcome comments regarding how such a pattern can be achieved.

Issue Analytics

  • State:open
  • Created 8 years ago
  • Reactions:295
  • Comments:181 (26 by maintainers)

github_iconTop GitHub Comments

74reactions
paul-gocommented, Feb 8, 2016

Is there a reason this issue was closed?

The fact that polymorphic this doesn’t work on statics basically makes this feature DOA, in my opinion. I’ve to date never actually needed polymorphic this on instance members, yet I’ve needed every few weeks on statics, since the system of handling statics was finalized way back in the early days. I was overjoyed when this feature was announced, then subsequently let down when realizing it only works on instance members.

The use case is very basic and extremely common. Consider a simple factory method:

class Animal
{
    static create(): this
    {
        return new this();
    }
}

class Bunny extends Animal
{
    hop()
    {
    }
}

Bunny.create().hop() // Type error!! Come on!!

At this point I’ve been either resorting to ugly casting or littering static create() methods in each inheritor. Not having this feature seems like a fairly large completeness hole in the language.

46reactions
FishOrBearcommented, Dec 18, 2018

Three years

Read more comments on GitHub >

github_iconTop Results From Across the Web

How does a static member variable behave with ...
Static members and class hierarchy don't interact. Polymorphism is about more behavioral forms. However you cant declare again ...
Read more >
Static Polymorphism in C++ - Medium
polymorphism — providing a single interface to entities of different types. virtual functions provide dynamic (run-time) polymorphism through an ...
Read more >
Static Polymorphism in C++ | Ruminations - Aaron Ballman
When using the CRTP, the Base class has access to the derived type through the template parameter. Due to the way templates work...
Read more >
Is C++ static polymorphism useful? - Sorush Khajepor
The static polymorphism should be used where there is no change of behaviour after compile-time. Therefore, if the code is an app that...
Read more >
Why static members can't be abstract and don't implement ...
Polymorphism is based on dynamic dispatch: you decide which method implementation to use based on (the class of) the object that receives a ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found