У меня есть функция с именем 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