microsoft/TypeScript

Primitive literals in computed property names

weswigham opened this issue · 11 comments

Looking at #4648 brought this up -

declare module JSX {
  interface IntrinsicElements {
    ["my-custom-element"]: MyCustomElementClass
  }
}

We should allow string literals in computed property names in interfaces. Right now we only allow well-know symbols, but allowing all primitive literals (of valid indexer types, I suppose) should be supported.

This is a spec change - section 2.2.3 would need to be updated to reflect this, but, IMO, is fairly important and worth the change. We can't strongly type, say, tslint.json result structures right now, as we lack this.

See #1082 for some previous discussion on computed property names in interfaces.

will this work in your case?

declare module JSX {
    interface IntrinsicElements {
        "my-element": __React.HTMLAttributes
    }
}

<my-element autoPlay/>

Huh. Why does our syntax for defining non-identifier string object properties in interfaces not overlap with the computed property syntax?

That's weird and unexpected.

It's quick info is also really weird:
image

That's... not valid JS in that quick info. It should certainly use square brackets, reflecting it's correct usage.

Yeah, still feels wrong:
image

Also, we don't get completions for this:
image

I guess that it reflects syntax for defining object literals. Also string\numeric literals as names in properties were allowed in TypeScript long before ES6 support was added

Weird - VSCode's syntax highlighter doesn't even think it's valid:
image

Like, I feel like the square brackets (computed property) should certainly be correct syntax in TS, even if the old interface syntax is still valid - just because it works for symbols, so it feels like it aught to work for other primitives.

I also don't think many people would argue with me that
image
is better written as
image

The top is feels almost nonsensical (I did not even realize that was valid TS until I tried it), the bottom is ES6 classes (and yet invalid in TS).

Both of those forms are valid in classes (where someone would actually migrate JS to TS). Would be reasonable to support both in interfaces for consistency sake.

Also was confused by this recently. Consider #2225
image

Don't really know if string literals should be in computed property names but you should be able to see those strings somewhere.

@jbondc I'm not really sure how #2225 ties in, but #606 is relevant.

@DanielRosenwasser in the chrome devtools, one can write

obj.t/**/

get completions at the marker, and recieve the list of properties

thing
thing-explainer
$thing
other-thing

select thing-explainer, and have it completed as

obj["thing-explainer"]/**/

I think this is the behavior we want to be able to replicate. (as far as completions go)

should be addressed in #5535