Как создать интерфейс TypeScript с подписью индекса и фиксированным свойством другого типа? - PullRequest
0 голосов
/ 29 ноября 2018

Из устаревшего API я получаю ответ JSON, например, так:

const someObject = {
    "general": {
        "2000": 50,
        "4000": 100,
        "8000": 200,
    },
    "foo": [
        0,
        1,
        2,
    ],
    "bar": [
        5,
        7,
    ],
    "baz": [
        8,
        9,
    ],
};

Имейте в виду, что все индексы, кроме "общего", являются динамическими и могут отсутствовать в ответе, я не могу набрать длякаждое свойство, но нужно использовать сигнатуру индекса.

Я хотел добиться этого через typescript@2.9.2:

interface ISomeObject {
    general: {
        [index: string]: number;
    };

    [index: string]?: number[];
}

, так как general всегда будет в ответе, однакодругие индексы могут быть или не быть там.

Проблема, с которой я сталкиваюсь:

  • Я не могу сделать [index: string]?: number[] необязательным, поскольку он будет жаловаться, что число используется в качестве значенияздесь.
  • [index: string]: number[] переопределит определение general: number и, следовательно, tsc будет жаловаться:

    Property 'general' of type '{ [index: string]: number; }' is not assignable to string index type 'number[]'.`
    

Могу ли я даже печатать для этого форматас интерфейсом TypeScript?

1 Ответ

0 голосов
/ 29 ноября 2018

Это вариант концепции TypeScript Dictarray .

. Исправлена ​​ошибка, из-за которой TypeScript сообщает, что все в порядке, и вы знаете, что делаете:

interface ISomeObject {
    [index: string]: number[];
    // @ts-ignore: I'm creating a Dictarray!
    general: {
        [index: string]: number;
    };
}

Компилятор будет правильно выводить типы возвращаемых данных, которые в данном случае являются числами:

let x: ISomeObject;

const a = x.general['idx'];
const b = x['idx'];

Связанная статья содержит больше информации, но это суть ее в вашем конкретном случае.

...