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

Allow any key type as an index signature parameter type #26797

Closed

Conversation

weswigham
Copy link
Member

@weswigham weswigham commented Aug 30, 2018

This allows, eg, symbol:

interface SymbolMap {
  [x: symbol]: string;
}

interface PropertyMap {
  [x: string | number | symbol]: string;
}

// same as
interface PropertyMap {
  [x: PropertyKey]: string;
}

enums:

enum Cardinal {
  North = "n",
  South = "s",
  West = "w",
  East = "e"
}
interface CardinalDataMap {
  [dir: Cardinal]: number;
}

enum Places {
  None,
  First,
  Second,
  Third
}
interface PlaceMap {
  [dir: Places]: number;
}

literal unions:

interface AdjacencyMap {
  [side: "top" | "bottom" | "left" | "right"]: number;
}

and generics:

interface PartialElementMap<TElements extends keyof HTMLElementTagNameMap> {
  [elem: TElements]: HTMLElement;
}

interface SpyProxy<T> {
  [field: keyof T]: Function;
}

as index signature parameter types.
Much of this functionality also exists in mapped types, except they had trouble shuffling around symbol information since there was no kind of index signature a symbol could map to. Unlike mapped types, however, since these are just index signatures, they can be added into any object type and in multiples.

Fixes #26470
Fixes #1863 (caveat: well-known symbols are not currently checked as part of a symbol index signature! Such checking should fall out from removing the concept of well-known symbols and using unique symbols instead)
Fixes #2491 in the original sense (rather than with mapped types).

Related: #28315

@weswigham
Copy link
Member Author

@typescript-bot test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Aug 30, 2018

Heya @weswigham, I've started to run the extended test suite on this PR at 2c47d31. You can monitor the build here. It should now contribute to this PR's status checks.

tommy20061222 pushed a commit to tommy20061222/safe-mock that referenced this pull request Oct 28, 2018
(2) typescript 2.9 not allow symbol to be used as index. microsoft/TypeScript#1863. Current there is a PR open to address this issue microsoft/TypeScript#26797
@jhpratt
Copy link

jhpratt commented Nov 22, 2018

@RyanCavanaugh I see you marked this for TS 3.2. Is that still the plan?

@DanielRosenwasser DanielRosenwasser removed this from the TypeScript 3.2 milestone Nov 29, 2018
@orta
Copy link
Contributor

orta commented Mar 18, 2021

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 18, 2021

Heya @orta, I've started to run the tarball bundle task on this PR at 05f63f6. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 18, 2021

Hey @orta, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/98697/artifacts?artifactName=tgz&fileId=FCFFE06ACEDE5A9CF492C0B487ADB414731BE223F7CF66D693D5A513375E6B9102&fileName=/typescript-4.3.0-insiders.20210318.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@4.3.0-pr-26797-61".;

@nana4gonta
Copy link

nana4gonta commented Mar 30, 2021

Hello, I found this PR and I am looking forward to its release.

A question about this PR.
I want to define an object type that can only accept a numeric string as a key.
In the following code, why does an error occur for the key "100"?

type NumStr = `${number}`
type Obj = { [key: `${NumStr}`]: string }
const obj: Obj = { 
    "0xff": "", // OK
    "100e10": "", // OK
    "100": "", // NG, but why?
}
// Type '{ "0xff": string; "100e10": string; "100": string; }' is not assignable to type 'Obj'.
// Object literal may only specify known properties, and '"100"' does not exist in type 'Obj'.

Playground Link

@RyanCavanaugh
Copy link
Member

#41821

@mykohsu
Copy link

mykohsu commented Jun 4, 2021

Could this support optional indexers? This seems to work with the in operator but not the : operator.

type OptionalKeyedType = {
  [k in typeof ENUM[keyof typeof ENUM]]?: unknown;
};

interface DirectOptionalKeyed {
  [k: typeof ENUM[keyof typeof ENUM]]?: unknown; // ';' expected.(1005)
}

Playground link

@MartinJohns
Copy link
Contributor

@weswigham What's the status of this? The PR is still open and has the "Backlog" milestone, yet on the roadmap it's marked as done and already part of typescript@next.

@ahejlsberg
Copy link
Member

What's the status of this?

It's been superseded by #44512.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team Experiment A fork with an experimental idea which might not make it into master For Backlog Bug PRs that fix a backlog bug For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet