Typescript: невозможно определить тип возвращаемого значения функции из нескольких условных типов - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь создать тип возвращаемого значения функции из нескольких условных типов.То, что я пытаюсь получить в качестве возвращаемых значений функции buildKindsFor - это объект, содержащий всевозможные варианты ключей, прикрепленных к функции.

Пример кода будет лучше, в первом все в порядке:

type KindNames =
  | 'one' | 'two' | 'three'

type KindShort<T extends  KindNames> =
  T extends 'one' ? 'o' : T extends 'two' ? 'tw' : 'th'

type KindPluralized<T extends  KindNames> =
  T extends 'one' ? 'ones' : T extends 'two' ? 'twos' : 'threes'

const buildKindsFor = <
  K extends KindNames,
  S extends KindShort<K>,
  P extends KindPluralized<K>,
>(
  kind: K,
  fn: (kind: KindNames, obj: any) => any,
): {
  [A in K]: () => any
} => {
  throw new Error ('Yet to implement !')
}

Но когда я пытаюсь добавить запись в объект возврата, скажем, в короткой версии, все ломается, например (ошибка повторяется, в комментариях появляются некоторые сообщения, когда я нахожув IDE):

const buildKindsFor = <
  K extends KindNames,
  S extends KindShort<K>, // Cannot find name K
  P extends KindPluralized<K>, // 'KindPluralized' only refers to a type, but is being used as a value here
>(
  kind: K,
  fn: (kind: KindNames, obj: any) => any,
): {
  [A in K]: () => any // ';' expected, ... and so on
  [B in S]: () => boolean
} => {
  throw new Error ('Yet to implement !')
}

Ожидаемый тип возврата для вызова, скажем, buildKindsFor ('one', dummyFn) должен быть примерно таким:

{
  one: () => any
  o: () => boolean
  ones: () => string
}

Заранее спасибо всем, кто мог бы указать мнечего мне не хватаетСеб

1 Ответ

0 голосов
/ 14 декабря 2018

Это синтаксическая ошибка в вашем отображаемом типе, приводящая к тому, что анализатор повсеместно становится несчастным.Вы не можете создать сопоставленный тип с двумя индексами.

{ [A in K]: () => any, [B in S]: () => boolean } // syntax error!

Либо используйте пересечение

{ [A in K]: () => any } & { [B in S]: () => boolean }

, либо сделайте индексатор объединением ключей, о которых вы заботитесь:

{ [A in K | S]: A extends K ? (() => any) : (() => boolean) }

Любой способ должен очистить этиошибки.


Кстати, второй и третий параметры типа S и P на самом деле не нужны, если я что-то упустил.Вы можете просто заменить S на KindShort<K> и P на KindPluralized<K>, и это должно работать для вас.


Надеюсь, это поможет;удачи!

...