Skip to content

Commit dd58aa6

Browse files
committed
refactor(@schematics/angular): avoid InsertChange type assumptions
This change introduces a helper function (`applyToUpdateRecorder`) that handles all known `Change` classes. The use of this helper function removes type assumptions within the schematics. Many of these assumptions caused compilation errors when strict TypeScript options are enabled.
1 parent 77681c6 commit dd58aa6

File tree

3 files changed

+33
-24
lines changed

3 files changed

+33
-24
lines changed

packages/schematics/angular/app-shell/index.ts

+9-15
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
insertImport,
2727
isImported,
2828
} from '../utility/ast-utils';
29-
import { Change, InsertChange } from '../utility/change';
29+
import { applyToUpdateRecorder } from '../utility/change';
3030
import { getAppModulePath } from '../utility/ng-ast-utils';
3131
import { targetBuildNotFoundError } from '../utility/project-targets';
3232
import { getWorkspace, updateWorkspace } from '../utility/workspace';
@@ -191,11 +191,7 @@ function addRouterModule(mainPath: string): Rule {
191191
const moduleSource = getSourceFile(host, modulePath);
192192
const changes = addImportToModule(moduleSource, modulePath, 'RouterModule', '@angular/router');
193193
const recorder = host.beginUpdate(modulePath);
194-
changes.forEach((change: Change) => {
195-
if (change instanceof InsertChange) {
196-
recorder.insertLeft(change.pos, change.toAdd);
197-
}
198-
});
194+
applyToUpdateRecorder(recorder, changes);
199195
host.commitUpdate(recorder);
200196

201197
return host;
@@ -248,9 +244,9 @@ function addServerRoutes(options: AppShellOptions): Rule {
248244
const routesChange = insertImport(moduleSource,
249245
modulePath,
250246
'Routes',
251-
'@angular/router') as InsertChange;
252-
if (routesChange.toAdd) {
253-
recorder.insertLeft(routesChange.pos, routesChange.toAdd);
247+
'@angular/router');
248+
if (routesChange) {
249+
applyToUpdateRecorder(recorder, [routesChange]);
254250
}
255251

256252
const imports = getSourceNodes(moduleSource)
@@ -269,18 +265,16 @@ function addServerRoutes(options: AppShellOptions): Rule {
269265
const routerModuleChange = insertImport(moduleSource,
270266
modulePath,
271267
'RouterModule',
272-
'@angular/router') as InsertChange;
268+
'@angular/router');
273269

274-
if (routerModuleChange.toAdd) {
275-
recorder.insertLeft(routerModuleChange.pos, routerModuleChange.toAdd);
270+
if (routerModuleChange) {
271+
applyToUpdateRecorder(recorder, [routerModuleChange]);
276272
}
277273

278274
const metadataChange = addSymbolToNgModuleMetadata(
279275
moduleSource, modulePath, 'imports', 'RouterModule.forRoot(routes)');
280276
if (metadataChange) {
281-
metadataChange.forEach((change: InsertChange) => {
282-
recorder.insertRight(change.pos, change.toAdd);
283-
});
277+
applyToUpdateRecorder(recorder, metadataChange);
284278
}
285279
host.commitUpdate(recorder);
286280
}

packages/schematics/angular/service-worker/index.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
2222
import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
2323
import { addSymbolToNgModuleMetadata, getEnvironmentExportName, insertImport, isImported } from '../utility/ast-utils';
24-
import { InsertChange } from '../utility/change';
24+
import { applyToUpdateRecorder } from '../utility/change';
2525
import { addPackageJsonDependency, getPackageJsonDependency } from '../utility/dependencies';
2626
import { getAppModulePath } from '../utility/ng-ast-utils';
2727
import { relativePathToWorkspaceRoot } from '../utility/paths';
@@ -63,7 +63,7 @@ function updateAppModule(mainPath: string): Rule {
6363
const change = insertImport(moduleSource, modulePath, importModule, importPath);
6464
if (change) {
6565
const recorder = host.beginUpdate(modulePath);
66-
recorder.insertLeft((change as InsertChange).pos, (change as InsertChange).toAdd);
66+
applyToUpdateRecorder(recorder, [change]);
6767
host.commitUpdate(recorder);
6868
}
6969
}
@@ -84,7 +84,7 @@ function updateAppModule(mainPath: string): Rule {
8484
const change = insertImport(moduleSource, modulePath, importModule, importPath);
8585
if (change) {
8686
const recorder = host.beginUpdate(modulePath);
87-
recorder.insertLeft((change as InsertChange).pos, (change as InsertChange).toAdd);
87+
applyToUpdateRecorder(recorder, [change]);
8888
host.commitUpdate(recorder);
8989
}
9090
}
@@ -97,9 +97,7 @@ function updateAppModule(mainPath: string): Rule {
9797
moduleSource, modulePath, 'imports', importText);
9898
if (metadataChanges) {
9999
const recorder = host.beginUpdate(modulePath);
100-
metadataChanges.forEach((change: InsertChange) => {
101-
recorder.insertRight(change.pos, change.toAdd);
102-
});
100+
applyToUpdateRecorder(recorder, metadataChanges);
103101
host.commitUpdate(recorder);
104102
}
105103

packages/schematics/angular/utility/change.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8+
import { UpdateRecorder } from '@angular-devkit/schematics';
9+
810
export interface Host {
911
write(path: string, content: string): Promise<void>;
1012
read(path: string): Promise<string>;
@@ -75,7 +77,7 @@ export class RemoveChange implements Change {
7577
order: number;
7678
description: string;
7779

78-
constructor(public path: string, private pos: number, private toRemove: string) {
80+
constructor(public path: string, private pos: number, public toRemove: string) {
7981
if (pos < 0) {
8082
throw new Error('Negative positions are invalid');
8183
}
@@ -101,8 +103,8 @@ export class ReplaceChange implements Change {
101103
order: number;
102104
description: string;
103105

104-
constructor(public path: string, private pos: number, private oldText: string,
105-
private newText: string) {
106+
constructor(public path: string, private pos: number, public oldText: string,
107+
public newText: string) {
106108
if (pos < 0) {
107109
throw new Error('Negative positions are invalid');
108110
}
@@ -125,3 +127,18 @@ export class ReplaceChange implements Change {
125127
});
126128
}
127129
}
130+
131+
export function applyToUpdateRecorder(recorder: UpdateRecorder, changes: Change[]): void {
132+
for (const change of changes) {
133+
if (change instanceof InsertChange) {
134+
recorder.insertLeft(change.pos, change.toAdd);
135+
} else if (change instanceof RemoveChange) {
136+
recorder.remove(change.order, change.toRemove.length);
137+
} else if (change instanceof ReplaceChange) {
138+
recorder.remove(change.order, change.oldText.length);
139+
recorder.insertLeft(change.order, change.newText);
140+
} else if (!(change instanceof NoopChange)) {
141+
throw new Error('Unknown Change type encountered when updating a recorder.');
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)