0

I read this article and I cannot understand the signature:

type FuncWithOneObjectArgument<P extends { [x: string]: any }, R> = (props: P) => R;

What does { [x: string]: any} mean? I supposed it's a dictionary with values of any type and keys of... what? List? Of strings?! What does x mean? I tried to remove x but it leads to syntax error... How to read the type?

RandomB
  • 3,367
  • 19
  • 30
  • Oh, God... so it's an object with index method getting `string` and returning `any`? – RandomB Dec 06 '19 at 13:51
  • it's an object which has string *properties* and the value of each property is of type `any`. For example `{"name": "Alice", "age": 42, "boss": {"name": "Bob"}}` – VLAZ Dec 06 '19 at 13:53
  • 1
    More on index types in the TS documentation: [interfaces](http://www.typescriptlang.org/docs/handbook/interfaces.html#indexable-types), [advanced types](http://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types) – VLAZ Dec 06 '19 at 13:57

1 Answers1

3

It define what the keys of your object can be. In your case, your keys can only be of type string. And your values can be whatever.

The reason behind this is that, in typescript, you can define an object to have certain property :

type obj = {property1: string, property2: any};

This create an type of object what MUST have both property to be valid.

Because of that, there is not intuitive way to define key type. Hense why we use the square bracket.

type obj = {[keys: string]: any};

For type like string and int it seams to be pointless, but you could use the union type operator to define what your keys can be :

type obj = {[keys in 'key1'|'key2'|'key3']: any};

This synthax is saying that your keys can only be key1, key2 or key3.

Nicolas
  • 8,077
  • 4
  • 21
  • 51
  • So why I cannot write just `{ string: any }` ? Why I need `[`, `]` brackets and this `x`? – RandomB Dec 06 '19 at 13:48
  • Because, you are not setting the values of your keys, you are defining an object that would have the property `string`. – Nicolas Dec 06 '19 at 13:49
  • 2
    `type obj = {[keys: 'key1'|'key2'|'key3']: any};` is invalid in at least TypeScript v3.6.3. Correct way to define a mapped type is `type obj = { [keys in 'key1' | 'key2' | 'key3']: any; };` – Joshua Chan Dec 06 '19 at 14:19
  • Is there solution to avoid any or unknown? It's important in case of destructing it. Any hints? – KamilMastalerz Oct 13 '22 at 09:58
  • @KamilMastalerz If you know the type of the keys in your object, you can use that instead of `any`. `type obj = {[key: string]: string}`. – Nicolas Oct 14 '22 at 12:08