Получение типа возврата функции, которая использует дженерики - PullRequest
0 голосов
/ 24 апреля 2018

Отказ от ответственности: следуют слишком упрощенные функции, я знаю, что они бесполезный

function thinger<T>(thing: T): T {
    return thing;
}

const thing = thinger({ a: "lol" });

thing.a;

Приведенный выше код переносится просто отлично. Но мне нужно поместить результат thinger<T> в объект.

interface ThingHolder {
    thing: ReturnType<typeof thinger>;
}

const myThingHolder: ThingHolder = {
    thing: thinger({ a: "lol" }),
};

Однако я потерял информацию о типе, поэтому myThingHolder.thing.a не работает

Свойство 'a' не существует для типа '{}'

Итак, я попробовал следующее

interface ThingHolder<T> {
    thing: ReturnType<typeof thinger<T>>;
}

const myThingHolder: ThingHolder<{ a: string }> = {
    thing: thinger({ a: "lol" }),
};

Но typeof thinger<T> не является допустимым машинописным текстом.

Как я могу получить тип возврата функции, у которой есть другой тип возврата, основанный на обобщениях?

1 Ответ

0 голосов
/ 24 апреля 2018

Я мог бы также поместить это в ответ, хотя это не похоже, что это удовлетворит ваши потребности. В настоящее время TypeScript не имеет ни общих значений , типов с более высоким родом , ни typeof для произвольных выражений . Обобщения в TypeScript являются своего рода «поверхностными» в этом смысле. Итак, насколько я знаю, к сожалению, нет способа описать функцию типа, которая вставляет параметры типа в универсальные функции и проверяет результат:

// doesn't work, don't try it
type GenericReturnType<F, T> = F extends (x: T) => (infer U) ? U : never

function thinger<T>(thing: T): T {
  return thing;
}

// just {}, ?
type ReturnThinger<T> = GenericReturnType<typeof thinger, T>;

Так что все, что я могу для вас сделать, это предложить обходные пути. Наиболее очевидный обходной путь - использовать псевдоним типа для описания того, что возвращает thinger(), а затем использовать его в нескольких местах. Это «обратная» версия того, что вы хотите; вместо извлечения возвращаемого типа из функции вы создаете функцию из возвращаемого типа:

type ThingerReturn<T> = T; // or whatever complicated type you have

// use it here
declare function thinger<T>(thing: T): ThingerReturn<T>;

// and here
interface ThingHolder<T> {
  thing: ThingerReturn<T>;
}

// and then this works ? 
const myThingHolder: ThingHolder<{ a: string }> = {
  thing: thinger({ a: "lol" }),
};

Это помогает? Я знаю, что это не то, что вы хотели, но, надеюсь, это по крайней мере возможный путь вперед для вас. Удачи!

...