Skip to content

Clarify why a property name is required in Index Signatures #60982

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

Closed
1 task done
gitspeaks opened this issue Jan 16, 2025 · 6 comments
Closed
1 task done

Clarify why a property name is required in Index Signatures #60982

gitspeaks opened this issue Jan 16, 2025 · 6 comments

Comments

@gitspeaks
Copy link

Acknowledgement

  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.

Comment

According to the TypeScript Handbook, the syntax for an index signature requires a property name, as shown in the example:

interface StringArray {
  [index: number]: string;
}

However, it seems like the following syntax could also work and might be more concise:

interface StringArray {
  [number]: string;
}

Could you please clarify in the documentation why a property name (like index in the example above) is required in index signatures? It would be helpful to understand its purpose, especially when it seems unused in the object definition.

@RyanCavanaugh
Copy link
Member

[something]: string is already the syntax for a computed property name, i.e. this is a legal program with a different meaning:

const number: unique symbol = Symbol();
interface Foo {
  [number]: number;
}

@gitspeaks
Copy link
Author

gitspeaks commented Jan 16, 2025

[something]: string is already the syntax for a computed property name

Aren’t variables named number or string rare edge cases? Instead of requiring a dummy identifier in every index signature, wouldn’t it make more sense for the compiler to flag a type error and ask the developer to rename the variable or require a dummy identifier only in those specific cases? The current approach feels unnecessarily verbose for something that might not happen often.

@RyanCavanaugh
Copy link
Member

Having one syntax do two completely different things depending on what an identifier means is confusing at best. Imagine if you had written something like this:

const foo: unique symbol = Symbol();
type foo = number;
interface Foo {
  [foo]: string;
}

@RyanCavanaugh
Copy link
Member

Related, we tried to say "You should not use type aliases for index signatures", and people were very unhappy with that answer: #1778 (comment)

@gitspeaks
Copy link
Author

we tried to say "You should not use type aliases for index signatures",

Exactly! What’s the point of constraining a property name to an alias of string or number? The constraint applies to all properties of Foo. What additional clarity or functionality does this provide that couldn’t already be conveyed through the interface name itself? It seems like an unnecessary layer of complexity that adds little value.

@gitspeaks
Copy link
Author

Having one syntax do two completely different things depending on what an identifier means is confusing at best.

I see your point. Personally, I find that understanding what computes a computed property often requires additional investigation beyond its name. In that sense, it might arguably be less confusing when you're in a position to trace the source of that identifier. It would be great to have an option to use a more concise syntax: The compiler will keep prioritizing the variable name of the computed property over a type identifier with the same name, as it currently does. If the type name identifier is preferred, it would still require a dummy variable under the current syntax. In all other cases, the behavior would indeed depend on what the identifier means. However, I suspect that in most scenarios, the identifier for an index signature would typically be a string or number, which should clearly indicate the intention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants