web-dev-qa-db-fra.com

TypeScript: un paramètre de signature d'index doit être une «chaîne» ou un «nombre» lorsque vous essayez d'utiliser une chaîne | nombre

J'essaie de créer une fonction pour normaliser mes tableaux et il attend un objet de sortie qui est structuré comme ceci:

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

OR

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

J'essaie de créer une interface appelée IOutput pour répondre à cela.

J'ai essayé ça:

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

Mais cela me donne l'erreur suivante

Un type de paramètre de signature d'index doit être "chaîne" ou "nombre". ts (1023)

Cela semble fonctionner quand je fais cela:

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

OR

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

Mais ce n'est pas ce que j'essaie d'accomplir. J'ai également essayé cela et cela me donne la même erreur:

type StringOrNumber = string | number

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

Comment puis-je accomplir ce que j'essaie de faire?

8

Il s'agit d'une limitation de la façon actuelle dont nous pouvons écrire des index (cela changera assez tôt ). Un paramètre de signature d'index ne peut être que number ou string (exactement ces types, pas leur union, pas les types littéraux). Vous pouvez cependant avoir deux signatures d'index, une pour number et une pour string.

Il existe un autre petit rapide, si vous avez une signature string, vous pouvez également indexer par number. Cela signifie donc que si l'index string et l'index number ont le même type de retour, vous avez juste besoin de l'index de chaîne

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': {}
    }
}