Ввод заводской функции - PullRequest
       5

Ввод заводской функции

0 голосов
/ 18 февраля 2019

У меня есть построенный во время выполнения список функций, которые инициализируются аргументом и возвращают разные вещи:

 mythings: [
   param => ({foo: param, bar: 2}),
   param => ({baz: param, qux: 4}),
 ]

Теперь я хочу написать фабричную функцию для создания подмножества этих вещей, например:

const createThings = (things) => things.map(thing => thing("param"));

Я изо всех сил пытаюсь набрать заводскую функцию.Моя недавняя попытка выглядит так:

// MyCreator?

const createThings = <T>(things: MyCreator<T>[]) =>
  things.map(thing => thing("param"));

Но эта попытка не работает.Есть идеи?

1 Ответ

0 голосов
/ 18 февраля 2019

Вы можете использовать сопоставленный массив / кортежи для извлечения типа возвращаемого значения из каждого элемента в массиве:

const mythings = [
   (param: string) => ({foo: param, bar: 2}),
   (param: string) => ({baz: param, qux: 4}),
 ]
type AllReturnTypes<T extends Array<(...a: any[])=> any>> = { 
    [P in keyof T]: T[P] extends (...a: any[])=> infer R?R:never
}

const createThings = <T extends Array<(...a: any[])=> any>>(things: T): AllReturnTypes<T> =>
  things.map(thing => thing("param") )as any; // assertion necessary unfortunately 

createThings(mythings) // ({ foo: string; bar: number; } | { baz: string; qux: number; })[]

Вы также можете сделать myThings типом кортежа, чтобы получить больше точных типов для каждого индексав результате:

function tuple<T extends any[]>(...a: T) {
    return a;
}
const mythings = tuple(
    (param: string) => ({ foo: param, bar: 2 }),
    (param: string) => ({ baz: param, qux: 4 }),
)

let r = createThings(mythings) // [{ foo: string; bar: number; }, { baz: string; qux: number; }

Или в машинописи 3.4 вы можете использовать as const:

const mythings = [
    (param: string) => ({ foo: param, bar: 2 }),
    (param: string) => ({ baz: param, qux: 4 }),
] as const
...