Есть ли способ удовлетворить некоторый интерфейс, основанный на поле enum? - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь создать универсальную функцию, которая будет возвращать мне точный интерфейс, основанный на аргументе enum, но любая попытка не удалась.

Может быть, я что-то упустил или делаю это просто неправильно?

Если я приведу результат к этому интерфейсу, все будет в порядке, но на самом деле это несколько бесполезно для меня.

enum Commands {
    Info = "info",
    Echo = "echo",
}

interface BaseRequest {
    command: Commands;
    timestamp: number;
}

interface InfoRequest extends BaseRequest {
    command: Commands.Info;
}

interface EchoRequest extends BaseRequest {
    command: Commands.Echo;
}

type GenericRequest = InfoRequest | EchoRequest;

const createRequest = (command: Commands) => ({
    command,
    timestamp: new Date().getTime(),
});

const sendRequest = (request: GenericRequest) => {};

const request = createRequest(Commands.Info);
sendRequest(request);

1 Ответ

1 голос
/ 06 апреля 2019

Существует два решения:

  1. Замените GenericRequest на BaseRequest в функции sendRequest, удалите тип GenericRequest.
  2. Сделать createRequest универсальным:
    const createRequest = <TCommand extends Commands>(command: TCommand) => ({
        command,
        timestamp: new Date().getTime(),
    });
    
    Таким образом, свойство command будет такого типа, что вы передадите аргумент command.

Объяснение состоит в том, что createRequest возвращает объект со свойством command всего типа Commands независимо от переданного типа. И тип GenericRequest в sendRequest определяет, что свойство command должно иметь тип InfoRequest или EchoRequest - оно не знает обо всех значениях перечисления Command.

...