microsoft / microsoft/TypeScript
Add a way to annote `super` paramerter in objec literal.
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 2 j 4 h
- PR mergées (30 j)
- 132
Description
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));
}
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
La charge utile ne nomme aucun fichier du dépôt, test ou point d’entrée par lequel commencer. Avant l’implémentation, la proposition a besoin d’une conception concrète et de tests d’acceptation pour saisir super dans des méthodes de littéral d’objet, y compris les exemples montrés de modification de prototypes.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript, typescript
- Domaine
- compilers
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 25/100