В TypeScript, как остановить параметр типа generi c для получения `unknown`-ed, когда он используется циклически? - PullRequest
2 голосов
/ 02 мая 2020

У меня есть функция с именем createDeferredObject, которая работает следующим образом:

const box = createDeferredObject({
  contents: (box) => [4, 8, 15, 16, 23, 42],
  description: (box) => `This box contains ${box.contents.length} number(s).`,
});

Я хочу, чтобы она была обобщенной c, позволяющей создавать объект с любыми ключами и любыми значениями. И я хочу, чтобы он мог выводить форму результирующего объекта на основе возвращаемых значений распознавателей. Например, в приведенном выше примере в идеальном случае тип box (включая тот, который был передан в резольвер description) будет иметь вид { contents: number[], description: string }.

. Вот как в идеале идеально набирается:

declare function createDeferredObject<TShape extends object>(
  init: DeferredObjectInit<TShape>
): TShape;

type DeferredObjectInit<TShape extends object> = {
  [K in keyof TShape]: (self: TShape) => TShape[K];
};

Цель здесь состоит в том, чтобы иметь возможность вывести тип TShape на основе заданного DeferredObjectInit<TShape>. К сожалению, используя приведенную выше сигнатуру типа, TypeScript не всегда правильно выводит TShape. В некоторых случаях это так, но как только создается круговая ссылка потенциальная , она выдает unknown. Пример, приведенный выше, является одним из таких случаев.

Существует ли способ статического ввода createDeferredObject таким образом, чтобы он мог выводить TShape при использовании такими способами, как в примере выше?

Подробнее: Я опубликовал Gist, содержащий пример реализации , другие примеры , deep-dive , показывающий, что именно Scenar ios делает и не вызывает сбой TypeScript, а список неудачных попыток для решения проблемы: https://gist.github.com/skfreddo/6658acd6a17dfeb6e56b75a284790169

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...