-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES6 Computed Properties #1082
Comments
I think the down-level should be apply or not apply to both classes and object literals. However, down-level one but not the other seems confusing and asymmetric to me. Some question
|
@yuit Your point about the symmetry of down leveling is well taken. To answer your questions:
|
Here is a proposal for how to emit them:
declare var staticProperty: string;
declare var instanceProperty: string;
declare var staticMethod: string;
declare var instanceMethod: string;
declare var instanceAccessor: string;
declare var staticAccessor: string;
class C {
static [staticProperty]: string = "a";
private [instanceProperty] : string = "i";
static [staticMethod]() { }
[instanceMethod]() { }
get [instanceAccessor] () { return 0 }
get [staticAccessor] () { return 0 }
} results in: var C = (function () {
var _instanceProperty;
function C() {
this[_instanceProperty] = "i";
}
C[staticProperty] = "a";
_instanceProperty = instanceProperty; // capture the value of the expression
C[staticMethod] = function () { };
C.prototype[instanceMethod] = function () { };
Object.defineProperty(C.prototype, instanceAccessor, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(C.prototype, staticAccessor, {
get: function () {
return 0;
},
enumerable: true,
configurable: true
});
return C;
})(); Notes:
declare function func(a: any): void;
declare var computed: string;
// Object literal
func({
before: 0,
[computed]: 1,
after : 2
}); var _$1 = {
before: 0
}, _$1[computed] = 1 ,
_$1.after = 2;
func(_$1); |
A few more notes:
What is the value of enabling this? // This looks silly
var x = { ["name"] : 0 }
This should also include object type literals
I am not sure i understand that, do you mean "checked against"? |
|
Also, I don't think the following emit will work: var _$1 = {
before: 0
}, _$1[computed] = 1 ,
_$1.after = 2;
func(_$1); Recall that a comma in a variable statement actually separates variable declarations from each other, so you need to use semicolons instead: var _$1 = {
before: 0
};
_$1[computed] = 1;
_$1.after = 2;
func(_$1); |
Some updates:
|
I'm updating this with the following changes:
|
Updating a few things:
I will update the proposal above to reflect these. |
Here is an interesting question. One thing that seems apparent is that we should check that the computed properties in a class conform to the indexer declared by that class. It seems equally natural to do this if the indexer is inherited. The question is, what about inherited computed properties? These properties never actually appear on the type, so one can argue that they do not get inherited. On the other hand, we know they are there! class Base {
["name"]() { }
}
class Derived extends Base {
[s: string]: number; // Error?
} |
Assigning to @ahejlsberg for spec integration. |
Could we just close this and make a new issue for spec work if this one was just to track the dev work? |
Opened a separate issue to track the spec work. |
@JsonFreeman @mhegazy Regarding downlevel emit for computed properties, for the example func({ before: 0, [computed]: 1, after : 2 }); we could use temporary variables and the comma operator to emit func((_a = { before: 0 }, _a[computed] = 1, _a.after = 2, _a));
var _a; This would work in any expression context and we already have the infrastructure in place to track and emit the temporary variable declaration (from my work on downlevel destructuring). |
Yes, that is a good idea. I will open two issues, one for downlevelling computed properties, and one for allowing them in class property declarations. |
@ahejlsberg I opened #1840 and #1841 |
Can we have an explanation as to why we disallow 'this' ? I believe the following code is valid ES6 and it worked in my limited testing (only tested chrome using the console). toObject() {
let o = {
[this.idField]: 12,
name: "dummy"
};
return o;
} I can understand this may not be possible in some contexts such as member initialisers or interfaces, however why is such usage blocked when composing objects within functions? |
The following code is valid TypeScript. Maybe it was fixed after the original proposal. class Foo {
idField: number;
toObject() {
let o = {
[this.idField]: 12,
name: "dummy"
};
return o;
}
} PS: It seems the |
Thanks @saschanaz. After some investigation it seems that this error is coming from ReShaper. I initially ruled our ReSharper as there was no options to ignore the error or configure the inspection severity. I'll open a new ticket with them. Update: Reported here: https://youtrack.jetbrains.com/issue/RSRP-460192 |
ES6 allows an arbitrary expression as the name of a property. The syntax is like this:
Here is my current proposal for supporting this feature:
Computed expressions would be allowed in the following places if target is ES6:
Below ES6:
Note that emit for all of the above is straightforward.
Type check:
Questions:
Argument for - we would want this to work:
Argument against - Computed properties would be allowed in class properties, so someone might have a class hierarchy like this:
The text was updated successfully, but these errors were encountered: