microsoft / microsoft/TypeScript

Add a way to annote `super` paramerter in objec literal.

Aperta
#42,327 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Awaiting More Feedback Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
1g 19h
PR unite (30g)
117

Descrizione

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));
}

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Il payload non indica alcun file del repository, test o punto di ingresso da cui iniziare. Prima dell’implementazione, la proposta necessita di un design concreto e di test di accettazione per digitare super nei metodi dei literal di oggetti, inclusi gli esempi mostrati di modifica dei prototipi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
javascript, typescript
Ambito
compilers
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.