typescript - 如何摆脱用于修复循环类型引用的接口(interface)

标签 typescript

我试图通过推断其元素类型来摆脱用作数组的接口(interface)。

type test(string | string[])[] , 但它应该是 string[][] .

我该如何解决这个问题?

type test = MyType<{ type: 'array'; items: { type: 'array'; items: { type: 'string' } } }>

type MyType<T> = T extends { type: 'string' }
  ? string
  : T extends { type: 'array' }
  ? UnpackMyArray<T extends { items: infer Items } ? MyArray<Items> : never>
  : never

interface MyArray<Declaration> extends Array<MyType<Declaration>> {}
type UnpackMyArray<T> = T extends Array<infer Item> ? Item[] : never

最佳答案

我希望我知道里面发生了什么,但我想不通。通过在接口(interface)中包装一个否则被禁止的自引用条件类型然后立即解开它来绕过循环类型检测器是一个技巧并且可能很脆弱。我已经看到针对 other such tricks 的警告;不确定这个最终会如何发展,但我会谨慎依赖它。 (请注意,如果您只是返回您的 MyArray 类型,这不会是一个问题……这里可疑的是额外的解包)。

无论如何,我尝试对其进行分析,但即使我对代码进行了微小的更改,最终也会使编译器混淆,足以输出类似 any 的类型。对于整个事情。最后,我重新创建了您的逻辑并删除了尽可能多的 conditional type inference尽可能将其替换为 property lookup types .类型推断比属性查找更“神奇”,而且我对推断的结果不如对查找的结果有信心。具体来说,我做了以下类型的更改:

  • 代替T extends {prop: infer P} ? P :我会用 T extends {prop: unknown} ? T['prop'] :

  • 代替T extends Array<infer L> ? L :我会用 T extends Array<any> ? T[number] : .

我还尽可能折叠了嵌套条件类型(但我看到你编辑了你的问题也这样做了)

  • 代替T extends {prop: infer P} ? P extends Q ? ... : never我崩溃到T extends {prop: Q} ? ... .

现在让我们看看你得到了什么:

type DeclarationType<D> = D extends { type: 'string' } ? string :
  (D extends { type: 'array', items: unknown } ? MyArray<D['items']> : never)[number][];

interface MyArray<D> extends Array<DeclarationType<D>> { }

type test = DeclarationType<{ 
  type: 'array'; items: { type: 'array'; items: { type: 'string' } } 
}>

这给了我 type test = string[][] ,如您所料。

Playground link


完美吗?可能不会。你能期望它在新版本的 TypeScript 中继续工作吗?谁知道。我是否使用截至 2019 年 4 月 26 日在 TS 3.3.3 上运行的版本以及我的笔记本电脑上现在的任何 TS 版本(碰巧是 TS 3.5.0-dev.20190424)从技术上回答了您的问题?嗯,是的!

希望对您有所帮助;祝你好运。

关于typescript - 如何摆脱用于修复循环类型引用的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55872531/

相关文章:

angular - "MapboxGeocoder is not a constructor"当尝试在我的组件的 ts 内初始化 MapboxGeocoder 时

json - 直接访问 JSON 对象属性并记录它

Angular 5 - 添加动态路由但不路由

angular - 你如何调试 Angular 6 库

node.js - 通过 Dockerfile 编译时出现 TSC 错误

javascript - 如何使用 Typescript 查询 Firebase?

typescript - typescript 签名中的函数获取 setter

javascript - 在 Typescript 和单元测试中,类型 .. 的参数不可分配给类型 .. 的参数

typescript - 删除 Typescript 的事件监听器不起作用

reactjs - 用空数组初始化的钩子(Hook)?