Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript: An index signature parameter must be a 'string' or 'number' when trying to use string | number

I'm attempting to create a function to normalize my arrays and it's expecting an output object that is structured like this:

{
  allIds: [1],
  byId: {
    1: {...}
  }
}

OR

{
  allIds: ['1'],
  byId: {
    '1': {...}
  }
}

I'm trying to create an interface called IOutput to cater for this.

I've tried this:

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: number | string]: any
  }
}

But it gives me the following error

An index signature parameter type must be 'string' or 'number'. ts(1023)

It seems to work when I do this:

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: number]: any
  }
}

OR

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: string]: any
  }
}

But that's not what I'm trying to accomplish. I've also tried this and it gives me the same error:

type StringOrNumber = string | number

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: StringOrNumber ]: any
  }
}

How can I accomplish what I'm trying to do?

like image 736
Barry Michael Doyle Avatar asked Apr 24 '19 13:04

Barry Michael Doyle


People also ask

How to use index signature typescript?

Index signature syntax The syntax of an index signature is pretty simple and looks similar to the syntax of a property, but with one difference. Instead of the property name, you simply write the type of the key inside the square brackets: { [key: KeyType]: ValueType } .

Why do we need Index signature typescript?

In typescript, Index Signature identifies key type for indexing of an object. Everytime an object in typescript is created and indexing is expected on that object then developers must specify Index Signature .

What is a signature in typescript?

A function signature (or type signature, or method signature) defines input and output of functions or methods. A signature can include: parameters and their types. a return value and type.

When to use index signature?

Index signature can be used to define the type of the object whose values are of consistent types or you don't know the structure of the object you are dealing with.


1 Answers

This is a limitation of the current way we can write indexes (this will change soon enough). An index signature parameter can only be number or string (exactly those types, not a union of them, not literal types). You can however have two index signatures, one for number and one for string.

There is another small quick, if you have a string signature, you can actually index by number as well. So this means that if the string index and the number index have the same return type you just need the string index

interface IOutput {
    allIds: string[] | number[]
    byId: {
        [key: string]: any
        // [key: number]: any // Valid but not necessary
    }
}

let o: IOutput = {
    allIds: [1],
    byId: {
        1: {}
    }
}
let o2: IOutput = {
    allIds: ['1'],
    byId: {
        '1': {}
    }
}
like image 140
Titian Cernicova-Dragomir Avatar answered Sep 22 '22 11:09

Titian Cernicova-Dragomir