Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
635 views
in Technique[技术] by (71.8m points)

interface - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...