-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Allow abstract class for local declarations and expressions #9110
Comments
Yes it should but it doesn't make a lot of sense to do. |
It might make sense according to the same rationale that TypeScript supports other local types. It would be helpful to see a motivating example showing the value of a local abstract class. Note this was sort-of anticipated in the proposal for abstract classes, under the heading "To Be Discussed". |
I had no real use case, I just wanted to scope the abstract class and its derived types to avoid having global symbols. The workaround was to use a surrounding namespace. It was an artificial sample for a TypeScript talk. Nevertheless, as local types (for non-abstract classes, interfaces, and enums) are supported, IMO missing support for abstract classes means that this feature is incomplete. Also because the compiler output seems to be correct (without |
I agree this should be supported I was just curious what the actual use case was since the base class cannot escape the function anyway, it's only implementations are going to reside within the same scope which should be fairly narrow. However if you're using the function to avoid polluting the global namespace but want to use an abstract class in your design that seems very reasonable. I've been spending too much time writing external modules... |
This is a use case for abstract class expressions: implementing mixins via subclass factories. const MyMixin = (S : { new () : Object }) => abstract class extends S {
abstract foo() {}
bar() {}
};
// Must implement foo()
class MyClass extends MyMixin(Object) {
} (I don’t feel 100% confident about the type of |
Unfortunately, the method you show wouldn't work even if we allowed abstract class expressions. class SuperClass {
superMethod() {}
}
const MyMixin = (S: { new(): Object }) => {
abstract class A extends S {
abstract foo(): void;
bar() {}
}
return A;
}
class MyClass extends MyMixin(SuperClass) {
foo() {}
}
new MyClass().bar();
// ERROR: Property 'superMethod' does not exist on type 'MyClass'.
new MyClass().superMethod(); The problem is that the return type of MyMixin doesn't take into account the specific type passed in by S. I'm assuming that the following is what you would want in a perfect world: class SuperClass {
superMethod() {}
}
abstract mixin Mixin {
abstract abstractMethod(): number;
mixinMethod() {
return this.abstractMethod() + 1;
}
}
class MyClass extends SuperClass and also extends Mixin {
abstractMethod() { return 1; }
}
new MyClass().superMethod();
new MyClass().mixinMethod(); Here's how you can get it done today: class SuperClass {
superMethod() {}
}
interface MixinAbstracts {
abstractMethod(): number;
}
interface Mixin {
// Implementation provided by factory
mixinMethod(): number;
}
function mixin<T extends { new(): Object }>(t: T): T {
return <any> class extends (<{new(): Object}>t) {
mixinMethod(this: MixinAbstracts) {
return this.abstractMethod() + 1;
}
}
}
interface X extends Mixin {}
class X extends mixin(SuperClass) implements MixinAbstracts {
abstractMethod() { return 1; }
ownMethod() {}
}
new X().superMethod();
new X().mixinMethod();
|
TypeScript Version:
1.8.9 / nightly (1.9.0-dev.20160612-1.0)
Code
Expected behavior:
It should be possible to define abstract classes within functions just like non-abstract ones.
The text was updated successfully, but these errors were encountered: