-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Can not extend built in types #1168
Comments
This is a general problem for any js library that exposes functions that are meant to be subclassable. If my library exports the Foo constructor and expects to receive instances of subclasses of Foo (not just objects implementing a Foo-like interface), there's currently no way to allow that. I would like to be able to say
There would be no javascript emitted for such a statement, only an update of Typescript's symbol table. For the general case, I'd like to be able to replace the body of any class declaration with a semicolon, allowing things like
which would mean that the library already guarantees that Foo.prototype is an instance of Bar.prototype and implements the Baz interface. |
@metaweta I think it may make some redundancies: interface Foo {
}
class Foo; // Foo is now a class!
interface Bar extends Foo {
}
class Bar extends Foo; // Two `extends Foo`s.
interface X {
}
class X extends Foo; // Hmm?
interface Y extends Foo {
}
class Y; // Hmm? It still have some potentials as the subclassable interfaces will work as open-ended classes. #819 |
@metaweta your first case should be handled by an ambient class declaration. e.g. // myLib.d.ts
declare class Error {
}
// no code emitted here for this. // myfile.ts
// Error is subclassable,
class MyError extends Error {
} For the second case, I would file a different suggestion issue for it. |
Here is the full list of "subclassable" objects from the ES6 spec. currently these are all defined as an interface/var pairs.
Problems:
Possible solutions:
|
@mhegazy Thanks, I was unaware of the ambient class declaration construct. |
When I extend the Error class this way (using ambient class definition), throwing the ExtendedError does not produce stack trace nor assign message properly.
|
@unional this looks like an engine issue. as per ES6 spec it should work. Engines should be fixing these now that ES6 has become ratified. |
I managed to get it to work. In my js code that was working, I have the Error.captureStackTrace call but I take it out when I implement it in ts because Error declaration doesn't have it. There is an example code:
|
Fixed by #3516. Classes can now extend arbitrary expressions of constructor function types. |
What release of TypeScript this fix is going to be shipped? EDIT: Thanks for your work! |
@kostrse you can try our nighty releases of TypeScript 1.6 by running |
Hi, I'm using Typescript 1.6.2 and my lib.es6.d.ts show Error (and Array, ...) as Interface not class. Cheers! |
@jpsfs the fix, as noted by @ahejlsberg in #1168 (comment) is to allow classes to extend arbitrary expressions of constructor function types. |
Even there is ability to extend export class HttpError extends Error {
httpCode: number;
message: string;
constructor(httpCode: number, message?: string) {
super();
if (httpCode)
this.httpCode = httpCode;
if (message)
this.message = message;
this.stack = new Error().stack;
}
} |
The ES6 designates some native objects as subclassable, e.g. Object, Boolean, Error, Map, Promise ..etc. The way these constructs are modeled in lib.d.ts makes is impossible to subclass, as they are defined as a pair of a var and an interface.
From the ES6 spec section19.5.1:
Currently this would result in "A class can only extend another class" error:
The text was updated successfully, but these errors were encountered: