ng-update schematic对象属性迁移异常:接口改名后属性未同步更新
问题描述
我正在为内部设计系统实现ng-update schematic,我们的包在两个版本间存在组件和接口重命名的情况,部分接口的属性也需要重命名。
我使用@angular/cdk包中的createMigrationSchematicRule方法,并提供如下迁移配置数据:
{ attributeSelectors: {}, classNames: { [TargetVersion.V17]: [ { pr: '', changes: [{ replace: 'Site', replaceWith: 'AppCenterSubject' }] } ] }, constructorChecks: {}, cssSelectors: {}, elementSelectors: {}, inputNames: {}, methodCallChecks: {}, outputNames: {}, propertyNames: { [TargetVersion.V17]: [ { pr: '', changes: [ { replace: 'site', replaceWith: 'name', limitedTo: { classes: ['Site'] } } ] } ] }, symbolRemoval: {} }
当我在如下组件上运行该schematic时:
@Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { public value: Site = { site: 'Site', group: 'Group' }; }
得到的输出结果如下:
@Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { public value: AppCenterSubject = { site: 'Site', group: 'Group' }; }
可以看到,Site接口已被迁移为新的AppCenterSubject接口,但value对象的site属性并未被迁移为新的name属性。请问是我遗漏了配置项,还是该场景本身不支持?
解决方案与说明
这是两个原因共同导致的:
- 匹配时机与范围问题:你在
propertyNames配置的limitedTo.classes里指定的是旧接口名Site,但迁移时接口名先被替换成了AppCenterSubject,后续属性匹配规则找不到对应关联的类型,自然不会执行替换。 - 规则覆盖范围限制:
createMigrationSchematicRule的propertyNames规则默认只处理类实例的属性访问(比如instance.site这种写法),并不覆盖对象字面量的属性键(也就是你代码里{ site: 'Site' }这种场景)。
要解决这个问题,你可以按以下思路调整:
- 方案一:添加自定义规则
编写额外的自定义迁移规则,通过TypeScript AST分析,找到所有类型标注为Site或AppCenterSubject的变量,定位其初始化的对象字面量,将其中的site属性键替换为name。 - 方案二:调整现有配置逻辑
先移除propertyNames里的limitedTo限制(如果全局替换不会引发冲突),直接替换所有对象字面量中的site属性;或者拆分迁移步骤,先完成接口重命名,再添加针对AppCenterSubject类型的属性替换规则。 - 方案三:扩展规则匹配范围
检查@angular/cdk的迁移工具是否支持扩展propertyNames的匹配范围,不过目前默认实现确实不包含对象字面量的属性键替换。
内容的提问来源于stack exchange,提问作者Mathias Van den Broek
相关产品推荐
相关产品推荐

