0

I see the TypeScript handbook, in the Advanced Types section, it has code like this:

interface Dictionary<T> {
    [key: string]: T;
}
let keys: keyof Dictionary<number>; // string | number
let value: Dictionary<number>['foo']; // number

I can't understand the ['foo'], if it just declare that the index is string?

hmm, i find that ['foo'] certainy not limit the var must be the value of key 'foo' of a dictionary, and the follow statements is equivalent:

let value: Dictionary<number>['foo'];
let value: Dictionary<number>['abc'];
let value: Dictionary<number>[string];

is it right?

  • 1
    Does this answer your question? [What does a TypeScript index signature actually mean?](https://stackoverflow.com/questions/58458308/what-does-a-typescript-index-signature-actually-mean) – ford04 Oct 31 '19 at 07:25
  • Have a look at that answer. Especially: "Third, index signatures imply the existence of any property you specifically ask for[.]" – ford04 Oct 31 '19 at 07:26
  • `Dictionary[string]` would probably not work but the rest are equivalent. `Dictionary['a']` just means "the type of the property `a` of `Dictionary`" and you know all types in the dictionary must be `T` – apokryfos Oct 31 '19 at 09:39

2 Answers2

0

You can access the types of an interface by accessing ['valueOfKey'] on the interface. For eg:

interface IMessage {
    id: string;
}

const value: IMessage['id'] = 1;

This will error out because id is declared as a string in IMessage and the value we are providing it is an number. Changing 1 to "1" would clear this error. Note that IMessage has only one property id and accessing any other property would result in an error on the accessor.

In the example you have provided, the interface is:

interface Dictionary<T> {
    [key: string]: T;
}

Accessing foo in Dictionary would give you the type when key is a string - which is T. The T passed is number:

let value: Dictionary<number>['foo'];
Agney
  • 18,522
  • 7
  • 57
  • 75
0

It works as expected.

The generic T refers to the object values that are defined under the string key.

For better understanding let see at the object of type Dictionary:

interface Dictionary<T> {
    [key: string]: T;
}

const obj: Dictionary<number> = {
 foo: 3, // ok
 abc: '' // wrong - value must be a number
}

If you get an obj['foo'] you'll get a number 3, right?

The same refers for Dictionary<number>['foo'] as you're requesting the type of Dictionary value under the 'foo' key so it will always return T (so number in our case).

As interface is an abstraction only you can pick whatever key you want so Dictionary<number>['abc'] still return the same.

abuduba
  • 4,986
  • 7
  • 26
  • 43
  • so, `let value: Dictionary['foo']` equals to `let value: Dictionary['abc']` – Xie Zhichao Oct 31 '19 at 08:21
  • Exactly, due to Dictionary expects a `string` value for a key. So if you give one, the output must be a number. Both `foo` and `abc` are strings so the result must be a `T` (number for your case )` – abuduba Oct 31 '19 at 09:21
  • see my additional post pls – Xie Zhichao Oct 31 '19 at 09:33
  • Yes, you're right. For further details please refer to the other answers like https://stackoverflow.com/questions/58458308/what-does-a-typescript-index-signature-actually-mean – abuduba Nov 13 '19 at 15:44