Как набрать тип возвращаемого значения в зависимости от входного параметра - PullRequest
3 голосов
/ 22 апреля 2020

У меня есть функция, которая получает аргумент options с атрибутом kind. Возможные значения для kind - это небольшой набор значений. Таким образом, это в основном enum.

в зависимости от kind, функция должна иметь другое возвращаемое значение. В то время как все возможные возвращаемые значения берутся из некоторого общего базового типа.

Я могу достичь того, что хочу, с помощью перегрузок, но тогда сама функция не очень хорошо набрана:

function test(options: Scenarios['bar']['options']): Scenarios['bar']['ret'];
function test(options: Scenarios['foo']['options']): Scenarios['foo']['ret'];
function test(options: any): any {
  ...
};

Есть ли хороший способ напечатать это с помощью дженериков? Было бы идеально, если бы if(options.kind === 'foo') { return ... } также правильно применял правильный тип возвращаемого значения.

Это то, что я пробовал, но это не работает.

type Base {
  a: string;
}

type Foo {
  b: string;
}

type Bar {
  c: string;
}

interface Scenarios {
  foo: { options: { kind: 'foo', input: string }, ret: Foo },
  bar: { options: { kind: 'bar' }, ret: Bar },
}

function test<S extends keyof Scenarios, O extends Scenarios[S]['options'], R extends Scenarios[S]['ret']>(options: O): R {
  const out: Partial<R> = {
    a: 'one',
  };
  if(options.kind === 'foo') {
    out.b = options.input;
  }
  if(options.kind === 'bar') {
    out.c = "whatever"
  }

  return out;
}

Здесь ни O, ни R Кажется, не правильно набран. Я получаю несколько ошибок:

  • a: 'one', ошибки с Литерал объекта может указывать только известные свойства, а 'a' не существует в типе 'Partial'
  • options.input ошибок с Свойство 'input' не существует для типа 'O'.
  • out.bout.c) ошибок с Свойство 'b' не существует не существует для типа «Частичное» .
...