microsoft / microsoft/TypeScript
Add a way to annote `super` paramerter in objec literal.
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 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));
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The payload names no repository files, tests, or entry points to start from. Before implementation, the proposal needs a concrete design and acceptance tests for typing super in object-literal methods, including the shown prototype-patching examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100