microsoft / microsoft/TypeScript
Proposal: Add new __construct helper for better ES5/ES6 class interop
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 117
Beschreibung
I propose we add a new helper to assist with class instance construction runtime semantics when extending ES6 built-in classes while compiling with --target ES5.
Background
Our current emit for classes for --target ES5 assumes that the superclass follows the same runtime semantics as the classes we emit. Generally this means that the constructor can be called as a function via call() or apply(). However, a number of ES6 built-in classes are specified to throw when not used as a constructor (i.e. Promise, Map, etc.), and other ES6 built-in classes return a value when called, ignoring the this value provided to call() or apply() (i.e. Error, Array, etc.).
Previously we provided guidance for possible workarounds for this to support the latter scenario, but we do not currently have a solution for the former scenario.
Proposal
The following code listing describes a new __construct helper that we would need to emit for any file that contains an explicit (or implicit, for property declarations) super() call:
class MyPromise extends Promise {
constructor(executor) {
super(executor);
}
}
// becomes...
var __extends = ...;
var __construct = (this && this.__construct) || (typeof Reflect !== "undefined" && Reflect.construct
? function (s, t, a, n) { return t !== null ? Reflect.construct(t, a, n) : s; }
: function (s, t, a) { return t !== null && t.apply(s, a) || s; });
var MyPromise = (function (_super) {
__extends(MyPromise, _super);
function MyPromise(executor) {
var _this = this;
var _newTarget = this.constructor;
_this = __construct(this, _super, [executor], _newTarget);
return _this;
}
return MyPromise;
})(Promise);
Benefits
- Allows down-level class emit to extend ES6 built-ins if running in an ES6 host by feature detecting
Reflect.construct. - Falls back to the existing behavior when running in an ES5 host.
- Handles
extends nullandextends xwhenxisnullin the same way as existing behavior. - Handles custom return values from
superin the same way as existing behavior.
Drawbacks
- Larger helper footprint
- Subclassing a built-in in an ES5 host has different runtime semantics than subclassing a built-in in an ES6 host:
- In ES5, subclassing
ArrayorErrorwill not have the correct prototype chain. The only solution is to explicitly set the prototype chain using the non-standard__proto__property as per established guidance.
- In ES5, subclassing
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Das Issue schlägt einen neuen __construct-Helfer für die ES5-Klassenausgabe vor, wenn ES6-Built-ins erweitert werden. Beginne damit, den vorhandenen __extends-Helfer und die Herabstufung der Klassenausgabe zu lokalisieren; der Vorschlag definiert die Feature-Erkennung für Reflect.construct und das Fallback-Verhalten. Als abgeschlossen gilt die Unterstützung der beschriebenen ES6-Host- und ES5-Host-Semantik, einschließlich extends null und benutzerdefinierter super-Rückgabewerte.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- javascript, typescript
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 30/100