TypeScript: возможно ли получить тип возвращаемого значения универсальной функции? - PullRequest
0 голосов
/ 24 октября 2018

Я экспортировал функцию из какого-то модуля, которая выглядит следующим образом:

export function MyFunc<A>() {
    return {
        foo: (in: A) => void
    }
}

Теперь, в каком-то другом модуле, я хочу поговорить о различных типах возврата MyFunc.Поскольку я не экспортировал тип, я буду использовать typeof, чтобы получить тип, который я хочу, учитывая значение MyFunc. В идеале я бы сделал следующее :

import { MyFunc } from "mymodule";
type MyFuncReturned<A> = ReturnType<typeof MyFunc<A>>;

function foo(): MyFuncReturned<string> {
   // ...
}

Хммм, это не работает;typeof может быть передано только значение, и мне не нравится моя попытка указать общий тип этого значения.

Лучшее, что я могу сделать, - это убедить TypeScript вывести определенные типы MyFunc из значений Iсоздал, а затем дал им псевдонимы отдельных типов, например:

const myFuncStringReturn = MyFunc<string>();
type MyFuncStringReturn = typeof myFuncStringReturn;

Чтобы не запускать MyFunc просто для получения информации о типе, я могу скрыть его за функцией и использовать ReturnType наit:

const myFuncStringReturn = () => MyFunc<string>();
type MyFuncStringReturn = ReturnType<typeof myFuncStringReturn>;

const myFuncBoolReturn = () => MyFunc<bool>();
type MyFuncBoolReturn = ReturnType<typeof myFuncBoolReturn>;

Это дает мне возможность, по одному типу за раз, говорить о различных типах возврата MyFunc, но это

  • Включает фактический код времени выполнениябыть написано, что TS может сделать вывод из.
  • Не позволяет мне говорить о MyFunc в более общем смысле.

Единственное «правильное» решение, которое я могу придумать, - это дублировать кучу информации типа, когдаЯ заявляю MyFunc:

export function MyFunc<A>(): MyFuncReturns<A> {
    return {
        foo: (in: A) => void
    }
}

export type MyFuncReturns<A> = {
    foo: (in: A) => void
}

Но теперь, когда я изменяю MyFunc, я должен обеспечить синхронизацию MyFuncReturns с ним.

Есть лиВ любом случае я могу получить такой тип, как MyFuncReturns<A>, учитывая только наше экспортированное значение MyFunc, без необходимости добавлять код времени выполнения или шаблон выше?

1 Ответ

0 голосов
/ 24 октября 2018

Существует предложение разрешить использование typeof с произвольными выражениями, чтобы разрешить такие вещи, как получение возвращаемого типа универсальных функций для аргумента определенного типа (см. здесь и здесь )

Более общий обходной путь, который работает сегодня, состоит в том, чтобы использовать универсальный класс с полем, которое связано с типом возврата функции.Затем мы можем извлечь поле класса.Поскольку для классов мы можем указать параметры универсального типа в выражениях типа, мы можем извлечь обобщенную форму возвращаемого типа:

export function MyFunc<A>() {
  return {
    foo: (os : A) => {}
  }
}

class Helper <T> {
  Return = MyFunc<T>()
}
type FuncReturnType<T> = Helper<T>['Return']
type ForBool = FuncReturnType<boolean> //  {foo: (os: boolean) => void;}
type ForString = FuncReturnType<string> //  {foo: (os: string) => void;}

Примечание Если у вас есть ограничения A, вам понадобитсядублировать их на T в Helper и FuncReturnType, что, к сожалению, неизбежно.

...