Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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.

# for free to join this conversation on GitHub. Already have an account? # 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