typescript - 如何摆脱用于修复循环类型引用的接口
问题描述
我试图通过推断其元素类型来摆脱用作 Array 的接口。
是,但应该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
解决方案
我希望我知道那里发生了什么,但我无法弄清楚。通过在接口中包装一个原本被禁止的自引用条件类型然后立即展开它来绕过循环类型检测器是一个技巧并且可能很脆弱。我已经看到针对其他此类技巧的警告;不知道这个最终会如何,但我会警惕依赖它。(注意,如果您只是返回您的类型,这不会是一个问题MyArray
......这是可疑的额外展开)。
无论如何,我试图分析它,但即使我对代码所做的微小更改最终都会使编译器感到困惑,以至于输出类型就像any
整个事情一样。最后,我重新创建了您的逻辑并尽可能多地删除了条件类型推断,将其替换为属性查找类型。类型推断比属性查找更“神奇”,而且我对推断结果的信心不如查找结果。具体来说,我进行了以下更改:
而不是
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[][]
正如你所期望的那样,这给了我。
完美吗?可能不是。你能期望它继续在新版本的 TypeScript 中工作吗?谁知道。我是否从 2019 年 4 月 26 日起在 TS 3.3.3 上运行的版本以及我的笔记本电脑上现在使用的任何版本的 TS(TS 3.5.0-dev.20190424)从技术上回答了您的问题?嗯,是的!
希望有帮助;祝你好运。
推荐阅读
- php - 如何洗牌/随机化数组并在php中显示随机条目
- scala - Spark 2.4.7 在写入 JSON 时忽略空字段
- javascript - 使用 JavaScript 预加载过多图像的严重问题
- flutter - Flutter 特征发现 - 右侧的 DescribedFeatureOverlay
- ruby-on-rails - 如何在 Blacklight 中为文档标题添加自定义逻辑?
- html - 图像在底角的 CSS 网格对齐,同时仍然具有以下文本
- kubernetes - 带有 kubernetes 的 odoo 没有使用我的默认插件
- javascript - Javascript:为什么 async/await 在这种情况下不起作用,而 setTimeout 工作得很好?
- apache - Apache2.4.6 Webdav 无法在 Centos7 上运行
- c++ - 编译时可选代码标准题