Skip to content
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

Computed properties (but not known symbols) #1752

Merged
merged 28 commits into from
Jan 26, 2015
Merged

Conversation

JsonFreeman
Copy link
Contributor

ES6 allows an arbitrary expression as the name of a property. The syntax is like this:

var x = {
   ["some" + "arbitrary" + "name"]: 0
}

Here is my current proposal for supporting this feature:

Computed expressions would be allowed in the following places if target is ES6:

  • Object literal properties
  • Class methods and accessors (both static and instance), but not property declarations.
  • 'this' references are not allowed in computed properties.
  • No parameter properties
  • Do not allow in interfaces
  • No enum members

Below ES6:

  • Computed properties are not allowed

Note that emit for all of the above is straightforward.

Type check:

  • All computed names must be of type string, number, or any (or eventually symbol)
  • No property will be added to the containing type based on a computed name.
  • Computed names that are not well known do not add a property to the type, but they will be included in the union type for the indexer, if the containing type has an indexer.

Questions:

  • Should an unknown name cause the surrounding type to have an indexer, if it wouldn't have acquired one otherwise? Our decision here is 'no'. Here is an argument for and against:

Argument for - we would want this to work:

var n = "some " + "unknown " + "name";
var obj = {
    [n]: 0;
};
var num = obj[n]; // This should be number

Argument against - Computed properties would be allowed in class properties, so someone might have a class hierarchy like this:

var n = "some " + "unknown " + "name";
class C {
    [n]: number;
}
class D extends C {
   foo: string; // Error because C was given an implicit indexer that D inherited, but foo doesn't conform to the indexer
}

"category": "Error",
"code": 2466
},
"A computed property name cannot reference a type parameter from its contained type.": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

containing type

if (grandparent.kind === SyntaxKind.ClassDeclaration || grandparent.kind === SyntaxKind.InterfaceDeclaration) {
// A reference to this grandparent's type parameters would be an error
if (result = getSymbol(getSymbolOfNode(grandparent).members, name, meaning & SymbolFlags.Type)) {
error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example of when this would happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a good example is tests\cases\conformance\es6\computedProperties\computedPropertyNames32.ts:

function foo<T>() { return '' }
class C<T> {
    [foo<T>()]() { }
}

I will add this snippet in a comment in the code as well.

if (hasComputedNameButNotSymbol(node)) {
return undefined;
}
Debug.assert(!hasComputedNameButNotSymbol(node));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ensure that either it does not have a computed name OR if it does, it has a symbol? I'm confused.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OR that it has no name!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to invent a term for this, and put a doc comment above the function that defines the term? I could call it a dynamic name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should discuss this; @yuit and I think that the "But" is a problem - it's just "And" but it indicates something that is contradictory in intuition.

hasDynamicName is not bad for starters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will change that. You're right, "but" is bad.

JsonFreeman added a commit that referenced this pull request Jan 26, 2015
Computed properties (but not known symbols)
@JsonFreeman JsonFreeman merged commit 7eb0aa1 into master Jan 26, 2015
@JsonFreeman JsonFreeman deleted the computedProperties branch January 26, 2015 20:52
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants