typescript необязательный тип индексатора, возвращающий тот же тип

#typescript

#typescript

Вопрос:

У меня есть следующие типы:

 export enum KeyCode {
  Alt = 'meta',
  Command = 'command',
  Ctrl = 'ctrl',
  DownArrow = 'down',
  Enter = 'enter',
  Escape = 'esc',
  LeftArrow = 'left',
  Mod = 'mod',
  RightArrow = 'right',
  UpArrow = 'up'
}


export interface ShortcutAction {
  keys: string | string[];
  action: string;
}

export type ShortcutHandler = (action: string, event: KeyboardEvent) => void;

export type KeyStroke = KeyCode | string;

export interface Combination {
  combination: KeyStroke[];
}

export interface Sequence {
  sequence: KeyStroke[];
}

export type ShortcutItem = KeyStroke | KeyStroke[] | Combination | Sequence;

export interface Shortcut {
  [key: string]: ShortcutItem;
}

export type ShortcutMap =
  | {
      [key: string]: Shortcut;
    }
  | Shortcut;

export const buildFromMap = (shortcutMap: ShortcutMap, key?: string ) => {
  const map = key ? shortcutMap[key] : shortcutMap;

  return buildShortcuts(map);
}

export const buildShortcuts = (map: Shortcut): ShortcutAction[] => {
  return [];
}

const singleShortcutMap: ShortcutMap = {
  MOVE_LEFT: [KeyCode.LeftArrow, 'a'],
  MOVE_RIGHT: [KeyCode.RightArrow, 'd']
};

const multipleShortcutMap: ShortcutMap = {
  key1: {
    MOVE_UP: 'a'
  },
  key2: {
    MOVE_UP: 'a'
  }
};

buildFromMap(singleShortcutMap);
buildFromMap(multipleShortcutMap, "key1");
  

Я хочу, чтобы ShortcutMap тип мог определять следующие 2 примера:

 const singleShortcutMap: ShortcutMap = {
  MOVE_LEFT: [KeyCode.LeftArrow, 'a'],
  MOVE_RIGHT: [KeyCode.RightArrow, 'd']
};

const multipleShortcutMap: ShortcutMap = {
  key1: {
    MOVE_UP: 'a'
  },
  key2: {
    MOVE_UP: 'a'
  }
};
  

Таким образом, он может необязательно иметь ключ, который возвращает Shortcut тип, или это Shortcut тип.

Я пробовал это:

 export type ShortcutMap =
  | {
      [key: string]: Shortcut;
    }
  | Shortcut;
  

Но он выходит как:

 string | {
    [key: string]: Shortcut;
} | Shortcut | string[] | Combination | Sequence
  

Итак, я не думаю, что я адекватно сужаю тип, но я не уверен, как в данном случае.

Я создал void;

export type KeyStroke = KeyCode | string;

export interface Combination {
combination: KeyStroke[];
}

export interface Sequence {
sequence: KeyStroke[];
}

export type ShortcutItem = KeyStroke | KeyStroke[] | Combination | Sequence;

export interface Shortcut {
[key: string]: ShortcutItem;
}

export type ShortcutMap =
| {
[key: string]: Shortcut;
}
| Shortcut;

export const buildFromMap = (shortcutMap: ShortcutMap, key?: string ) => {
const map = key ? shortcutMap[key] : shortcutMap;

return buildShortcuts(map);
}

export const buildShortcuts = (map: Shortcut): ShortcutAction[] => {
return [];
}

const singleShortcutMap: ShortcutMap = {
MOVE_LEFT: [KeyCode.LeftArrow, ‘a’],
MOVE_RIGHT: [KeyCode.RightArrow, ‘d’]
};

const multipleShortcutMap: ShortcutMap = {
key1: {
MOVE_UP: ‘a’
},
key2: {
MOVE_UP: ‘a’
}
};

buildFromMap(singleShortcutMap);
buildFromMap(multipleShortcutMap, «key1″);» rel=»nofollow noreferrer»>игровую площадку, чтобы проиллюстрировать это