首页 > 解决方案 > 在 TypeScript 中,如何阻止泛型类型参数在循环使用时获得 `unknown`-ed?

问题描述

我有一个名为的函数createDeferredObject,其工作原理如下:

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

我希望它是通用的,允许创建具有任何键和任何值的对象。我希望它能够根据解析器的返回值推断结果对象的形状。例如,在上面的示例中,理想情况下,它将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,其中包含示例实现更多示例深入了解哪些场景会导致 TypeScript 退出和不会导致 TypeScript 退出,以及解决问题的失败尝试列表: https://gist .github.com/skfreddo/6658acd6a17dfeb6e56b75a284790169

标签: typescript

解决方案


推荐阅读