145

Closed

Support for abstract classes

description

Nothing seems to prevent the compiler to supports abstract classes, this could only be a compile time problem for it to write methods from the Abstract classes into each of its implementors. Right after this, at runtime those classes types (for type verification etc.) would be used as interfaces types are.
Closed Jul 28 at 10:17 PM by jonturner
As part of our move to GitHub, we're closing our CodePlex suggestions and asking that people move them to the GitHub issue tracker for further discussion. Some feature requests may already be active on GitHub, so please make sure to look for an existing issue before filing a new one.

You can find our GitHub issue tracker here:
https://github.com/microsoft/typeScript/issues

comments

billti wrote Dec 28, 2012 at 8:41 PM

There are no plans currently for any kind of abstract class syntax. If you have some compelling scenarios that would benefit from their implementation in JavaScript, please open a thread in the "Discussions" section (perhaps under "Language Specification"). Thanks!

rb126 wrote Mar 4, 2013 at 11:19 AM

How about:
module Shapes {
    // Interface for all shapes
    export interface Shape {
        draw(surface: Drawing.ISurface): void;
    }

    // Helper base class - implements lots of common code for all shapes
    export class ShapeBase implements Shape {
        constructor(public x: number, public y: number) { }

        draw(surface: Drawing.ISurface): void {
            // I CAN'T IMPLEMENT THIS - I'M AN ABSTRACT BASE CLASS AND CAN'T DRAW
            throw new Error('I want to catch this at compile time!!!');
            // THERE IS NO REASON I SHOULD NEED TO IMPLEMENT THIS
        }
    }

    export class Circle extends ShapeBase {
        constructor(x: number, y: number, radius: number) {
            super(x, y);
            this.m_radius = radius;
        }
        
        draw(surface: Drawing.ISurface): void {
            // This is OK - I know how to draw myself
        }

        m_radius: number;
    }
}
This sort of thing crops up a lot and it would be nice to be able to handle this in TypeScript rather than resort to runtime errors if a call occurs to a method I am forced to implement even though it doesn't make sense.

Or is there an alternative way to stop ShapeBase objects being created? Then at least I could catch the error at compile time, even though I would still be forced to implement a method that can never be called!

rb126 wrote Mar 6, 2013 at 8:56 AM

It would be great, in my previous example, if we could write something like:
export abstract class ShapeBase implements Shape {
    constructor(public x: number, public y: number) { }
}

export abstract class ShapeBaseEx extends ShapeBase {
    constructor(public x: number, public y: number, public foo: string) {
        super(x, y);
    }
}
and have the compiler not complain about draw not being implemented in either. I.e. classes should be able to extend/implement base classes and interfaces but remain abstract (non-instantiable) and not be forced to implement all methods of the parent item. It is preferable that those method be compile-time (type) checkable rather than handled with runtime errors.

WilliamMoy wrote Apr 11, 2013 at 5:13 AM

Abstract classes are not needed to model common idioms in JavaScript in a strongly-typed fashion, so I think this feature deserves less priority than other features like "this" typing.

However, abstract classes are very common in object-oriented programming. In our code base, we already have a several of instances where we are doing the following to "mimic" abstract classes:
class X {
    public abstractMethod() {
        throw new Method("This is an abstract method");
    }
}

Tekool wrote Apr 11, 2013 at 6:03 AM

If advatanges of using TypeScript over JavaScript are minimized to losing time using a new environment I don't want to wrk with, I will stay JavaScript. Thanks.

gavinwahl wrote Jul 14, 2013 at 1:41 AM

I started a thread as suggested: https://typescript.codeplex.com/discussions/449920.

jamesnw wrote Aug 12, 2013 at 1:46 PM

I'd like this as well, thanks. :)

jamesnw wrote Aug 12, 2013 at 1:52 PM

@Tekool: First of all, Typescript is in Alpha stage, so expect lack of features and more changes to come. Second, Typescript IS JavaScript for the most part. I can right an entire .js file in a .ts file and it outputs pretty much the same thing. I can then simply (and optionally) enforce the function parameter types, or variables, to make development easier (not to mention the intellisense is a huge help). Between intellisense and type checking, I've gotten further faster.

Shuping wrote Aug 24, 2013 at 2:06 AM

This is definitely what we want.

rb126 wrote Dec 13, 2013 at 9:16 AM

Surely all we need from TypeScript here is:

(a) The compiler to not insist that methods in derived classes are implemented if the class is marked abstract (so, probably, the support for an 'abstract' keyword before class definitions), and

(b) The compiler to shout if you ever try to instantiate an abstract class.

That's it, isn't it? And just by adding that we'd all gain a really common and powerful feature of object-oriented design that could avoid loads of bugs by catching these common situations at compile time, whilst the best we can do at the moment is try to throw an exception at run-time.

Could this feature please be prioritised? It's been classes as "low impact" and look how many votes it now has!

Thanks 8-)

jamesnw wrote Apr 14 at 8:03 AM

@rb126 I totally agree - not sure what the point of voting is if requests can simply be categorized as "low" when hundreds have voted! :/

jamesnw wrote Apr 14 at 8:12 AM

I agree with rb126's first post. I keep wanting to declare base event methods that, by default, should be undefined until defined later by the end users of the class. Currently I have to test if the "instance property" == "the prototype property" which is just silly (or create work arounds to erase the prototype function properties later).

PatrickMetz wrote Apr 17 at 10:31 AM

+1'd for stronger OOP support.

agwidarsito wrote Jun 18 at 1:03 AM

The discussion forum has a partial view of it being an anti-pattern, causing issues I believe. I don't agree, and I think it's with reference to the "too easily abused" paradigm it falls under. A feature shouldn't be prohibited due to this. If so, Regex tops the list on removal!

iislucas wrote Jun 22 at 3:13 AM

I have a team of 10 working fulltime working in typescript; I'd love abstract types. There are so many reasons!

1) One of the most compelling in my mind is that indexes typically come from somewhere. e.g. we have some mappings that are maintained between indexes. Because all indexes are strings, it's easy to use the an index variable for one mapping in another one by mistake. Because all indexes are strings, no error is given. If I could have abstract index classes this would be fixed.

2) Certain classes of functions (e.g. callbacks) can be important to be distinguished even though they have the same type. e.g. "() => void" often captures a side-effect producing function. Sometimes you want to control which ones are put into an event handler. Currently there's no way to type-check them.

huge +1 for having abstract types from me and my team. I'm happy to discuss in person/phone etc and explain what we're up. We're big fans of typescript and are using it for a pretty big project

iislucas wrote Jun 22 at 6:38 AM

Oh, here's another common case: you have different interfaces that have different optional parameters, but either no required ones, or the same required ones. In typescript, you will not get a compiler error for using one when you need another. Sometimes this is ok, but very often this is very not ok and you would love to have a compiler error rather than be confused at runtime. :)