Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
TypeScript 递归获取类字段属性_创想鸟

TypeScript 递归获取类字段属性

typescript 递归获取类字段属性

本文旨在解决 TypeScript 中递归获取类字段属性时遇到的 “Type instantiation is excessively deep and possibly infinite” 错误。通过修改类型定义,特别是针对 `Map` 类型的特殊处理,以及保留字段的可选性,提供了一种避免无限递归并正确获取字段类型的方法。

在 TypeScript 中,使用递归类型定义来处理复杂的数据结构是很常见的。然而,不当的递归类型定义可能导致编译器报错,提示 “Type instantiation is excessively deep and possibly infinite”。这个问题通常发生在类型定义过于复杂,导致编译器无法在合理的深度内完成类型推断时。本文将探讨如何解决这个问题,并提供一个具体的示例,展示如何递归地获取类字段的属性,同时排除函数类型,并保留字段的可选性。

理解问题根源

“Type instantiation is excessively deep and possibly infinite” 错误通常是由于类型定义中的循环依赖造成的。例如,一个类型 A 的定义依赖于类型 B,而类型 B 的定义又依赖于类型 A。如果这种依赖关系没有明确的终止条件,编译器就会陷入无限递归,最终报错。

在处理类字段属性时,如果类包含嵌套的复杂类型(例如,数组、Map、Set 等),并且递归类型定义没有针对这些类型进行特殊处理,就很容易触发这个错误。

解决方案:改进递归类型定义

为了解决这个问题,我们需要改进递归类型定义,使其能够正确处理各种类型,并避免无限递归。以下是一种可行的解决方案:

快转字幕 快转字幕

新一代 AI 字幕工作站,为创作者提供字幕制作、学习资源、会议记录、字幕制作等场景,一键为您的视频生成精准的字幕。

快转字幕 357 查看详情 快转字幕 限制递归深度: 虽然 TypeScript 本身没有直接限制递归深度的机制,但可以通过一些技巧来间接实现。例如,可以添加一个类型参数来表示递归深度,并在每次递归调用时递减该参数。当参数达到某个阈值时,停止递归。特殊处理 Map 类型: Map 类型是导致无限递归的常见原因。我们需要在递归类型定义中显式地检查 Map 类型,并对其进行特殊处理。一种方法是先检查类型是否为 Map,如果是,则进一步推断键和值的类型,并对值类型进行递归处理。保留字段的可选性: 在获取类字段属性时,我们需要保留字段的可选性。这意味着如果一个字段是可选的(使用 ? 标记),那么在递归类型定义中也应该保持其可选性。明确终止条件: 递归类型定义必须有一个明确的终止条件。例如,当类型为原始类型(如 string、number、boolean 等)时,停止递归。

代码示例

以下是一个改进后的代码示例,展示了如何递归地获取类字段的属性,同时排除函数类型,并保留字段的可选性:

type DeepWritablePrimitive = undefined | null | boolean | string | number | Function;type DeepWritable =  | T extends DeepWritablePrimitive ? T  : T extends (infer U)[] ? DeepWritable[]  : T extends Map ? (    T extends Map ? Map<K, DeepWritable> : never  )  : T extends Set ? Set<DeepWritable>  : DeepWritableRecord;type WritableKeys = {  [P in keyof T]: T[P] extends Function ? never : P}[keyof T];type DeepWritableRecord = {  // need to keep optionality  [K in keyof Pick<T, WritableKeys>]: DeepWritable}class Base {  set(data?: Partial<DeepWritable>) {    Object.assign(this, data);  }}class Parent extends Base {  name?: string;  arr?: Parent[];  map?: Map;};const record = new Parent();record.set({  // https://github.com/microsoft/TypeScript/issues/34933  arr: [{    name: '0'  }],  map: new Map([['key', {name: 'map_value'}]])})console.log(record.arr);console.log(record.map?.get('key')?.name);

在这个示例中,DeepWritable 类型定义递归地处理了数组、Map 和 Set 类型,并保留了字段的可选性。WritableKeys 用于排除函数类型的字段。

注意事项

在处理复杂的类型定义时,建议逐步构建类型,并使用 TypeScript 的类型检查器来验证类型的正确性。如果仍然遇到 “Type instantiation is excessively deep and possibly infinite” 错误,可以尝试简化类型定义,或者使用类型别名来减少类型的嵌套深度。在某些情况下,可能需要使用类型断言来绕过类型检查器的限制。但是,应该谨慎使用类型断言,因为它可能会导致运行时错误。

总结

通过改进递归类型定义,我们可以解决 TypeScript 中 “Type instantiation is excessively deep and possibly infinite” 错误,并正确地获取类字段的属性。关键在于限制递归深度,特殊处理 Map 类型,保留字段的可选性,并明确终止条件。希望本文能够帮助你更好地理解和解决这个问题。

以上就是TypeScript 递归获取类字段属性的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/309935.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
thinkphp设置说明
上一篇 2025年11月5日 04:52:04
实现字符到自定义数字映射:从ASCII到特定值的转换
下一篇 2025年11月5日 04:52:21

相关推荐

发表回复

登录后才能评论
关注微信