Динамически генерировать тип из массива перечислений - PullRequest
1 голос
/ 16 января 2020

Я пытаюсь построить какой-нибудь динамический c генератор функций. Есть несколько частей.

  1. Перечисление имен функций, FuncName
  2. Перечисление типов ввода, InputType с такими вещами, как String, Email, et c.
  3. A InputMap: Record<FuncName, IInput[]>, где IInput - это что-то вроде {label: string, type: InputType}, а InputType - просто простое перечисление. label будет уникальным для каждого входа.
  4. A FuncMap: Record<FuncName, SomeFunctionType>
  5. Отображение типов ввода на примитивы, type InputTypeToPrimitive = {[InputType.String]: string, [InputType.Email]: string, ...} (дополнительный вопрос, могу ли я набрать InputTypeToPrimitive, чтобы заставить его чтобы все ключи InputType были представлены?)

Я пытаюсь набрать аргументы SomeFunctionType. В идеале для данного FuncName значение SomeFunctionType будет вынуждено принимать аргументы соответствующего IInput.

Если бы я динамически создавал нужный мне тип, JS выглядел бы так:

const argumentTypes = {};
InputMap[someFuncName].forEach(input => {
    argumentTypes[input.label] = InputTypeToPrimitive[input.type]
});
return argumentTypes;

Мне интересно, есть ли чистый способ сделать это с помощью машинописи? такой, что я могу ввести аргумент значения SomeFunctionType в FuncName

1 Ответ

0 голосов
/ 16 января 2020

Это не совсем то, о чем вы просили, но мне интересно, решит ли это вашу проблему другим способом.

type FuncInAndOuts<T> = T extends ((...input: infer P) => infer R) ? [P, R] : never;

Учитывая функцию в качестве параметра типа T, FuncInAndOuts<T> возвращает tuple [P, R], где P - массив всех входных данных T, а R - тип возвращаемого значения функции.

Например, для данных двух функций

// convert a number to a string
const stringify = (n: number) => '' + n

// convert n to a string and concatenate with str
const stringifyTwo = (n: number, str: string) => '' + n + str

FuncInAndOuts возвращает эти описания своих входов и выходов

type Stringify = FuncInAndOuts<typeof stringify>
// type Stringify = [[number], string]

type StringifyTwo = FuncInAndOuts<typeof stringifyTwo>
// type StringifyTwo = [[number, string], string]

Помогает ли это вам достичь того, чего вы хотите?

...