Skip to content

Commit 96b6a16

Browse files
committed
refactor: add explicit types for createBuilder exports
This is necessary as with the new compilation, leveraging pnpm-linked first party dependencies, there are cases **during migration** where multiple locations of the same package exist. e.g. - `@angular_devkit/architect/node_modules/@angular-devkit/core` (pnpm package output) - `@angular_devkit/core` (plain js sources) This is fine, and there is no risk of wrong types, and this should only occur during migration anyway, but it causes a few type issues as TypeScript is unable to emit proper types for inference. This is okay, as we'd likely even want to make use of `isolatedDeclarations` at some point, but we just add explicit types right now. (also making `Builder` type more type safe, checking assignability properly).
1 parent 4fee94a commit 96b6a16

File tree

12 files changed

+73
-25
lines changed

12 files changed

+73
-25
lines changed

goldens/public-api/angular_devkit/architect/index.api.md

+12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ export class Architect {
2525
scheduleTarget(target: Target, overrides?: json.JsonObject, scheduleOptions?: ScheduleOptions): Promise<BuilderRun>;
2626
}
2727

28+
// @public
29+
export interface Builder<OptionT extends json.JsonObject = json.JsonObject> {
30+
// (undocumented)
31+
[BuilderSymbol]: true;
32+
// (undocumented)
33+
[BuilderVersionSymbol]: string;
34+
// (undocumented)
35+
__OptionT: OptionT;
36+
// (undocumented)
37+
handler: JobHandler<json.JsonObject, BuilderInput, BuilderOutput>;
38+
}
39+
2840
// @public
2941
export interface BuilderContext {
3042
addTeardown(teardown: () => Promise<void> | void): void;

packages/angular/build/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ ts_project(
107107
"//packages/angular/ssr:ssr_rjs",
108108
"//packages/angular/ssr/node:node_rjs",
109109
"//packages/angular_devkit/architect:architect_rjs",
110+
"//packages/angular_devkit/core:core_rjs",
110111
],
111112
)
112113

packages/angular/build/src/builders/application/index.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
9+
import { Builder, BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
10+
import { json } from '@angular-devkit/core';
1011
import assert from 'node:assert';
1112
import fs from 'node:fs/promises';
1213
import path from 'node:path';
@@ -259,4 +260,7 @@ function generateFullPath(
259260
return fullFilePath;
260261
}
261262

262-
export default createBuilder(buildApplication);
263+
const builder: Builder<ApplicationBuilderOptions & json.JsonObject> =
264+
createBuilder(buildApplication);
265+
266+
export default builder;

packages/angular/build/src/builders/dev-server/index.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { createBuilder } from '@angular-devkit/architect';
9+
import { Builder, createBuilder } from '@angular-devkit/architect';
10+
import { json } from '@angular-devkit/core';
1011
import { execute } from './builder';
1112
import type { DevServerBuilderOutput } from './output';
1213
import type { Schema as DevServerBuilderOptions } from './schema';
@@ -16,7 +17,12 @@ export {
1617
type DevServerBuilderOutput,
1718
execute as executeDevServerBuilder,
1819
};
19-
export default createBuilder<DevServerBuilderOptions, DevServerBuilderOutput>(execute);
20+
const builder: Builder<DevServerBuilderOptions & json.JsonObject> = createBuilder<
21+
DevServerBuilderOptions,
22+
DevServerBuilderOutput
23+
>(execute);
24+
25+
export default builder;
2026

2127
// Temporary export to support specs
2228
export { execute as executeDevServer };

packages/angular/build/src/builders/extract-i18n/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { createBuilder } from '@angular-devkit/architect';
9+
import { Builder, createBuilder } from '@angular-devkit/architect';
10+
import { json } from '@angular-devkit/core';
1011
import { execute } from './builder';
1112
import type { Schema as ExtractI18nBuilderOptions } from './schema';
1213

1314
export { ExtractI18nBuilderOptions, execute };
14-
export default createBuilder<ExtractI18nBuilderOptions>(execute);
15+
16+
const builder: Builder<ExtractI18nBuilderOptions & json.JsonObject> =
17+
createBuilder<ExtractI18nBuilderOptions>(execute);
18+
19+
export default builder;

packages/angular/build/src/builders/ng-packagr/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { createBuilder } from '@angular-devkit/architect';
9+
import { Builder, createBuilder } from '@angular-devkit/architect';
10+
import { json } from '@angular-devkit/core';
1011
import { execute } from './builder';
1112
import type { Schema as NgPackagrBuilderOptions } from './schema';
1213

1314
export { type NgPackagrBuilderOptions, execute };
14-
export default createBuilder<NgPackagrBuilderOptions>(execute);
15+
16+
const builder: Builder<NgPackagrBuilderOptions & json.JsonObject> =
17+
createBuilder<NgPackagrBuilderOptions>(execute);
18+
19+
export default builder;

packages/angular_devkit/architect/src/create-builder.ts

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import { Builder, BuilderSymbol, BuilderVersionSymbol } from './internal';
3737
import { JobInboundMessageKind, createJobHandler } from './jobs';
3838
import { scheduleByName, scheduleByTarget } from './schedule-by-name';
3939

40+
export type { Builder };
41+
4042
// eslint-disable-next-line max-lines-per-function
4143
export function createBuilder<OptT = json.JsonObject, OutT extends BuilderOutput = BuilderOutput>(
4244
fn: BuilderHandlerFn<OptT>,
@@ -252,6 +254,9 @@ export function createBuilder<OptT = json.JsonObject, OutT extends BuilderOutput
252254
handler,
253255
[BuilderSymbol]: true,
254256
[BuilderVersionSymbol]: require('../package.json').version,
257+
// Only needed for type safety around `Builder` types.
258+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
259+
__OptionT: null!,
255260
};
256261
}
257262

packages/angular_devkit/architect/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ import * as jobs from './jobs';
1010

1111
export * from './api';
1212
export { Architect, type ScheduleOptions } from './architect';
13-
export { createBuilder } from './create-builder';
13+
export { createBuilder, type Builder } from './create-builder';
1414

1515
export { jobs };

packages/angular_devkit/architect/src/internal.ts

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface Builder<OptionT extends json.JsonObject = json.JsonObject> {
5757
// Metadata associated with this builder.
5858
[BuilderSymbol]: true;
5959
[BuilderVersionSymbol]: string;
60+
__OptionT: OptionT;
6061
}
6162

6263
export interface ArchitectHost<BuilderInfoT extends BuilderInfo = BuilderInfo> {

packages/angular_devkit/build_webpack/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ ts_project(
5050
"//:node_modules/webpack",
5151
"//:node_modules/webpack-dev-server",
5252
"//packages/angular_devkit/architect:architect_rjs",
53+
"//packages/angular_devkit/core:core_rjs",
5354
],
5455
)
5556

packages/angular_devkit/build_webpack/src/builders/webpack-dev-server/index.ts

+13-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { BuilderContext, createBuilder } from '@angular-devkit/architect';
9+
import { Builder, BuilderContext, createBuilder } from '@angular-devkit/architect';
10+
import { json } from '@angular-devkit/core';
1011
import { resolve as pathResolve } from 'path';
1112
import { Observable, from, isObservable, of, switchMap } from 'rxjs';
1213
import webpack from 'webpack';
@@ -124,12 +125,15 @@ export function runWebpackDevServer(
124125
);
125126
}
126127

127-
export default createBuilder<WebpackDevServerBuilderSchema, DevServerBuildOutput>(
128-
(options, context) => {
129-
const configPath = pathResolve(context.workspaceRoot, options.webpackConfig);
128+
const builder: Builder<WebpackDevServerBuilderSchema & json.JsonObject> = createBuilder<
129+
WebpackDevServerBuilderSchema,
130+
DevServerBuildOutput
131+
>((options, context) => {
132+
const configPath = pathResolve(context.workspaceRoot, options.webpackConfig);
130133

131-
return from(getWebpackConfig(configPath)).pipe(
132-
switchMap((config) => runWebpackDevServer(config, context)),
133-
);
134-
},
135-
);
134+
return from(getWebpackConfig(configPath)).pipe(
135+
switchMap((config) => runWebpackDevServer(config, context)),
136+
);
137+
});
138+
139+
export default builder;

packages/angular_devkit/build_webpack/src/builders/webpack/index.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
9+
import { Builder, BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
10+
import { json } from '@angular-devkit/core';
1011
import { resolve as pathResolve } from 'path';
1112
import { Observable, from, isObservable, of, switchMap } from 'rxjs';
1213
import webpack from 'webpack';
@@ -120,10 +121,13 @@ export function runWebpack(
120121
);
121122
}
122123

123-
export default createBuilder<WebpackBuilderSchema>((options, context) => {
124-
const configPath = pathResolve(context.workspaceRoot, options.webpackConfig);
124+
const builder: Builder<WebpackBuilderSchema & json.JsonObject> =
125+
createBuilder<WebpackBuilderSchema>((options, context) => {
126+
const configPath = pathResolve(context.workspaceRoot, options.webpackConfig);
125127

126-
return from(getWebpackConfig(configPath)).pipe(
127-
switchMap((config) => runWebpack(config, context)),
128-
);
129-
});
128+
return from(getWebpackConfig(configPath)).pipe(
129+
switchMap((config) => runWebpack(config, context)),
130+
);
131+
});
132+
133+
export default builder;

0 commit comments

Comments
 (0)