microsoft / microsoft/TypeScript
Add a way to annote `super` paramerter in objec literal.
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
Suggestion
🔍 Search Terms
super parameter object literal
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
⭐ Suggestion
We could using super in object literals:
var obj1 = {
method1() {
console.log('method 1');
}
}
var obj2 = {
method2() {
super.method1();
}
}
Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // logs "method 1"
The value of super is determined at runtime, like this. And we already could explicit this parameter like following example`:
function f(this: void) {
// make sure `this` is unusable in this standalone function
}
There could add a way to annote super paramerter in objec literal:
let parent = { /* some props */ }
let child = {
method1(super: typeof parent){
//
}
}
It won't break the existing codes we aleary have, cause super is a keyword, we can't use it as a formal argument.
📃 Motivating Example
When extends some object provide by runtime enviroment which have no constructor for us to extend, we can do this:
before:
function patchA(origin: IOrigin){
let patch = {
mehtod1(arg: any){
// do some compability work
origin.method1(arg);
},
//...
}
return Object.setPrototypeof(patch, originObj);
}
function patchB(origin: IOrigin){
let patch = {
mehtod1(arg: any){
// do some compability work
origin.method1(arg);
},
//...
}
return Object.setPrototypeof(patch, originObj);
}
after:
let patchA = {
mehtod1(super: IOrigin, arg: any){
// do some compability work
// type friendly to use super here
super.method1(arg);
},
}
let patchB = {
mehtod1(super: IOrigin, arg: any){
// do some compability work
// type friendly to use super keyword here
super.method1(arg);
},
}
function doPatch(patch, origin: IOrigin){
return Object.setPrototypeof(patch, origin);
}
💻 Use Cases
I'm writing a lib about canvas now, it run on multiple platforms, web, weixin-miniprogram, uniapp-h5, uniapp-mp-weixin...
There is some difference on canvas context api. Additionally, same api on different platform are act slightly different.
In web, canvas context's interface is CanvasRenderingContext2D, in wieixn-miniprogram and uniapp, context's interface is CanvasContext. In my lib, it's PainterContext which is much like CanvasContext.
First, I try to use adptor pattern to handle this.
class PainterH5Context extends CanvasRenderingContext2D implements PainterContext {
async drawImage(imageResource: string, sx: number, sy: number){
const imageElement = await createImageElement(imageResource);
super.drawImage(imageResource: string, sx: number, sy: number);
}
}
but, new a CanvasRenderingContext2D instance is forbid in browser, It also violate the rule that child class should implement parent's all interface, casue signature of drawImage were different.
So I directly handle prototype chain.
function patchH5Context (context: CanvasRenderingContext2D): PainterContext {
let patch = {
async drawImage(imageResource: string, sx: number, sy: number){
const imageElement = await createImageElement(imageResource);
context.drawImage(imageResource, sx, sy);
}
}
// use createExtendableContextProto to make methods on contenxt bind context itself
// otherwise it with rise an error when invoke
return Object.setPrototypeof(patch, createExtendableContextProto(context));
}
I want extract the patch object out of the function. cause function logic are same on different platforms.
To implement that I use the super keyword, but I can't get any type intellesence:
let h5ContextPatch = {
async drawImage(imageResource: string, sx: number, sy: number){
const imageElement = await createImageElement(imageResource);
super.drawImage(imageElement, sx, sy);
}
}
let UniContextPatch = {
async drawImage(imageResource: string, sx: number, sy: number){
const tempPath = await dowloadFiles(imageResource);
super.drawImage(tempPath, sx, sy);
}
}
function doPatch(patch: Partial<PainterContext>, context: CanvasRenderingContext2D | CanvasContext){
return Object.setPrototypeof(patch, createExtendableContextProto(context));
}
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
Die Payload nennt keine Repository-Dateien, Tests oder Einstiegspunkte, mit denen begonnen werden kann. Vor der Implementierung benötigt der Vorschlag ein konkretes Design und Abnahmetests für die Eingabe von super in Methoden von Objekt-Literalen, einschließlich der gezeigten Beispiele zum Patchen von Prototypen.
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
- 25/100