From 7e6d946c0f039ca511a1c599d103103c505cda05 Mon Sep 17 00:00:00 2001 From: Jason Hartman Date: Fri, 19 Jun 2026 23:50:55 +0000 Subject: [PATCH] build(build-tools): enable exactOptionalPropertyTypes Update build-tools packages to use exactOptionalPropertyTypes:true in normal build as well as check exactOptionalPropertyTypes:false successfully type checks (no emit, skipLibCheck). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Fixes build-tools: - common/biomeConfigUtils.ts  — Conditionally spread  stopAt  only when defined, avoiding passing  undefined  to the  find-up  library's  Options.stopAt  which expects  string . - fluidBuild/commonOptions.ts  — Changed  defaultRoot  and  root  from optional properties ( ?: string ) to required properties with explicit  undefined  in the union ( string | undefined ), allowing direct assignment from  process.env . - fluidBuild/fluidRepo.ts  — Removed explicit  ignoredDirs: undefined  assignment; conditionally spread  ignoredDirs  only when the mapped value is defined. - fluidBuild/tasks/workers/apiExtractorWorker.ts  — Split return into two distinct object literals (success without  error , failure with  error ) instead of assigning  undefined  to the optional  error  property. - fluidBuild/tsCompile.ts  — Conditionally spread  projectReferences  only when  commandLine.projectReferences  is defined, avoiding passing  undefined  to TypeScript API's  CreateProgramOptions . version-tools: - commands/version.ts  — Conditionally spread  bumpType  only when defined, avoiding  undefined  assignment to an optional property. --- build-tools/packages/build-cli/package.json | 4 ++++ .../tsconfig.inexactOptionalPropertyTypes.json | 8 ++++++++ .../packages/build-infrastructure/package.json | 8 ++++++++ .../tsconfig.inexactOptionalPropertyTypes.json | 8 ++++++++ build-tools/packages/build-tools/package.json | 8 ++++++++ .../build-tools/src/common/biomeConfigUtils.ts | 5 ++++- .../build-tools/src/fluidBuild/commonOptions.ts | 4 ++-- .../build-tools/src/fluidBuild/fluidRepo.ts | 4 ++-- .../fluidBuild/tasks/workers/apiExtractorWorker.ts | 14 +++++++------- .../build-tools/src/fluidBuild/tsCompile.ts | 4 +++- .../tsconfig.inexactOptionalPropertyTypes.json | 8 ++++++++ build-tools/packages/build-tools/tsconfig.json | 1 + build-tools/packages/version-tools/package.json | 8 ++++++++ .../packages/version-tools/src/commands/version.ts | 2 +- .../packages/version-tools/src/test/tsconfig.json | 1 + .../tsconfig.inexactOptionalPropertyTypes.json | 8 ++++++++ build-tools/packages/version-tools/tsconfig.json | 1 + fluidBuild.config.cjs | 10 +++++++++- 18 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 build-tools/packages/build-cli/tsconfig.inexactOptionalPropertyTypes.json create mode 100644 build-tools/packages/build-infrastructure/tsconfig.inexactOptionalPropertyTypes.json create mode 100644 build-tools/packages/build-tools/tsconfig.inexactOptionalPropertyTypes.json create mode 100644 build-tools/packages/version-tools/tsconfig.inexactOptionalPropertyTypes.json diff --git a/build-tools/packages/build-cli/package.json b/build-tools/packages/build-cli/package.json index 5bddc8b0b9b8..619946bf9b77 100644 --- a/build-tools/packages/build-cli/package.json +++ b/build-tools/packages/build-cli/package.json @@ -40,6 +40,7 @@ "build:test": "tsc --project ./src/test/tsconfig.json", "check:biome": "biome check .", "check:format": "npm run check:biome", + "check:inexactOptionalPropertyTypes": "tsc --project ./tsconfig.inexactOptionalPropertyTypes.json", "ci:build:docs": "api-extractor run", "clean": "rimraf --glob dist lib oclif.manifest.json \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc", "clean:manifest": "rimraf --glob oclif.manifest.json", @@ -192,6 +193,9 @@ "...", "build:copy", "build:diagrams" + ], + "check:inexactOptionalPropertyTypes": [ + "^tsc" ] } }, diff --git a/build-tools/packages/build-cli/tsconfig.inexactOptionalPropertyTypes.json b/build-tools/packages/build-cli/tsconfig.inexactOptionalPropertyTypes.json new file mode 100644 index 000000000000..2ebd7d4dc5a1 --- /dev/null +++ b/build-tools/packages/build-cli/tsconfig.inexactOptionalPropertyTypes.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "exactOptionalPropertyTypes": false, + "skipLibCheck": true, + }, +} diff --git a/build-tools/packages/build-infrastructure/package.json b/build-tools/packages/build-infrastructure/package.json index cdd80c8dd538..5c4b5680545f 100644 --- a/build-tools/packages/build-infrastructure/package.json +++ b/build-tools/packages/build-infrastructure/package.json @@ -34,6 +34,7 @@ "build:test": "tsc --project ./src/test/tsconfig.json", "check:biome": "biome check .", "check:format": "npm run check:biome", + "check:inexactOptionalPropertyTypes": "tsc --project ./tsconfig.inexactOptionalPropertyTypes.json", "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" nyc _api-extractor-temp", "compile": "fluid-build . --task compile", "eslint": "eslint --quiet --format stylish src", @@ -93,6 +94,13 @@ "typedoc": "^0.28.14", "typedoc-plugin-markdown": "^4.9.0" }, + "fluidBuild": { + "tasks": { + "check:inexactOptionalPropertyTypes": [ + "^tsc" + ] + } + }, "oclif": { "bin": "buildProject", "dirname": "buildProject", diff --git a/build-tools/packages/build-infrastructure/tsconfig.inexactOptionalPropertyTypes.json b/build-tools/packages/build-infrastructure/tsconfig.inexactOptionalPropertyTypes.json new file mode 100644 index 000000000000..2ebd7d4dc5a1 --- /dev/null +++ b/build-tools/packages/build-infrastructure/tsconfig.inexactOptionalPropertyTypes.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "exactOptionalPropertyTypes": false, + "skipLibCheck": true, + }, +} diff --git a/build-tools/packages/build-tools/package.json b/build-tools/packages/build-tools/package.json index 8203222bea5f..cad491cb89d8 100644 --- a/build-tools/packages/build-tools/package.json +++ b/build-tools/packages/build-tools/package.json @@ -24,6 +24,7 @@ "build:test": "tsc --project ./src/test/tsconfig.json", "check:biome": "biome check .", "check:format": "npm run check:biome", + "check:inexactOptionalPropertyTypes": "tsc --project ./tsconfig.inexactOptionalPropertyTypes.json", "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" nyc", "compile": "fluid-build . --task compile", "eslint": "eslint --quiet --format stylish src", @@ -86,5 +87,12 @@ }, "engines": { "node": ">=22.22.2" + }, + "fluidBuild": { + "tasks": { + "check:inexactOptionalPropertyTypes": [ + "^tsc" + ] + } } } diff --git a/build-tools/packages/build-tools/src/common/biomeConfigUtils.ts b/build-tools/packages/build-tools/src/common/biomeConfigUtils.ts index 10f563451a35..262e3e20591c 100644 --- a/build-tools/packages/build-tools/src/common/biomeConfigUtils.ts +++ b/build-tools/packages/build-tools/src/common/biomeConfigUtils.ts @@ -54,7 +54,10 @@ export async function getClosestBiomeConfigPath( stopAt?: string, ): Promise { return (await findUp) - .findUp(["biome.json", "biome.jsonc"], { cwd, stopAt }) + .findUp(["biome.json", "biome.jsonc"], { + cwd, + ...(stopAt === undefined ? {} : { stopAt }), + }) .then((config) => { if (config === undefined) { throw new Error(`Can't find biome config file`); diff --git a/build-tools/packages/build-tools/src/fluidBuild/commonOptions.ts b/build-tools/packages/build-tools/src/fluidBuild/commonOptions.ts index 0dce28864dee..6e365375549a 100644 --- a/build-tools/packages/build-tools/src/fluidBuild/commonOptions.ts +++ b/build-tools/packages/build-tools/src/fluidBuild/commonOptions.ts @@ -4,8 +4,8 @@ */ interface CommonOptions { - defaultRoot?: string; - root?: string; + defaultRoot: string | undefined; + root: string | undefined; timer: boolean; logtime: boolean; quiet: boolean; diff --git a/build-tools/packages/build-tools/src/fluidBuild/fluidRepo.ts b/build-tools/packages/build-tools/src/fluidBuild/fluidRepo.ts index 479c33778475..74e5ba2c5e81 100644 --- a/build-tools/packages/build-tools/src/fluidBuild/fluidRepo.ts +++ b/build-tools/packages/build-tools/src/fluidBuild/fluidRepo.ts @@ -38,13 +38,13 @@ export class FluidRepo { if (typeof item === "string") { return { directory: path.join(resolvedRoot, item), - ignoredDirs: undefined, }; } const directory = path.join(resolvedRoot, item.directory); + const ignoredDirs = item.ignoredDirs?.map((dir) => path.join(directory, dir)); return { directory, - ignoredDirs: item.ignoredDirs?.map((dir) => path.join(directory, dir)), + ...(ignoredDirs === undefined ? {} : { ignoredDirs }), }; }; const loadOneEntry = (item: IFluidBuildDir, group: string): Package[] => { diff --git a/build-tools/packages/build-tools/src/fluidBuild/tasks/workers/apiExtractorWorker.ts b/build-tools/packages/build-tools/src/fluidBuild/tasks/workers/apiExtractorWorker.ts index 9022f06c4998..d375b867e0a6 100644 --- a/build-tools/packages/build-tools/src/fluidBuild/tasks/workers/apiExtractorWorker.ts +++ b/build-tools/packages/build-tools/src/fluidBuild/tasks/workers/apiExtractorWorker.ts @@ -35,14 +35,14 @@ export async function apiExtractorWorker(message: WorkerMessage): Promise messages.push(message), }); - return { - code: result.succeeded ? 0 : 1, - error: result.succeeded - ? undefined - : // This error does not appear to be used in fluid-build's output, + return result.succeeded + ? { code: 0 } + : { + code: 1, + // This error does not appear to be used in fluid-build's output, // but populate it with useful information anyway. - new Error( + error: new Error( `Number of Errors: ${result.errorCount}. Messages: ${JSON.stringify(messages.map((m) => m.text))}`, ), - }; + }; } diff --git a/build-tools/packages/build-tools/src/fluidBuild/tsCompile.ts b/build-tools/packages/build-tools/src/fluidBuild/tsCompile.ts index f5486e4310fe..9219c76cba44 100644 --- a/build-tools/packages/build-tools/src/fluidBuild/tsCompile.ts +++ b/build-tools/packages/build-tools/src/fluidBuild/tsCompile.ts @@ -158,7 +158,9 @@ export function tsCompile( tscUtils.convertOptionPaths(commandLine.options, cwd, path.resolve), ), host, - projectReferences: commandLine.projectReferences, + ...(commandLine.projectReferences === undefined + ? {} + : { projectReferences: commandLine.projectReferences }), }; const program = incremental ? baseTs.createIncrementalProgram(param) diff --git a/build-tools/packages/build-tools/tsconfig.inexactOptionalPropertyTypes.json b/build-tools/packages/build-tools/tsconfig.inexactOptionalPropertyTypes.json new file mode 100644 index 000000000000..2ebd7d4dc5a1 --- /dev/null +++ b/build-tools/packages/build-tools/tsconfig.inexactOptionalPropertyTypes.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "exactOptionalPropertyTypes": false, + "skipLibCheck": true, + }, +} diff --git a/build-tools/packages/build-tools/tsconfig.json b/build-tools/packages/build-tools/tsconfig.json index 15662ee0a09c..8c1651500181 100644 --- a/build-tools/packages/build-tools/tsconfig.json +++ b/build-tools/packages/build-tools/tsconfig.json @@ -15,6 +15,7 @@ "module": "node16", "moduleResolution": "node16", "types": ["node"], + "exactOptionalPropertyTypes": true, }, "include": ["src/**/*.ts", "src/**/*.cts"], "exclude": ["src/test/**/*", "dist", "node_modules"], diff --git a/build-tools/packages/version-tools/package.json b/build-tools/packages/version-tools/package.json index e4f575925176..8bea40cf373e 100644 --- a/build-tools/packages/version-tools/package.json +++ b/build-tools/packages/version-tools/package.json @@ -35,6 +35,7 @@ "build:test": "tsc --project ./src/test/tsconfig.json", "check:biome": "biome check .", "check:format": "npm run check:biome", + "check:inexactOptionalPropertyTypes": "tsc --project ./tsconfig.inexactOptionalPropertyTypes.json", "ci:build:docs": "api-extractor run", "clean": "rimraf --glob dist lib oclif.manifest.json \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc", "clean:manifest": "rimraf --glob oclif.manifest.json", @@ -103,6 +104,13 @@ "engines": { "node": ">=22.22.2" }, + "fluidBuild": { + "tasks": { + "check:inexactOptionalPropertyTypes": [ + "^tsc" + ] + } + }, "oclif": { "bin": "fluv", "dirname": "fluv", diff --git a/build-tools/packages/version-tools/src/commands/version.ts b/build-tools/packages/version-tools/src/commands/version.ts index bb04e646d0d4..866647a1ebf3 100644 --- a/build-tools/packages/version-tools/src/commands/version.ts +++ b/build-tools/packages/version-tools/src/commands/version.ts @@ -189,7 +189,7 @@ export default class VersionCommand extends Command { this.error(`The version you provided isn't valid: "${parsedInput}"`); } return { - bumpType, + ...(bumpType === undefined ? {} : { bumpType }), parsedVersion, isFluidInternalFormat: isInternalVersionScheme(parsedVersion) === true, }; diff --git a/build-tools/packages/version-tools/src/test/tsconfig.json b/build-tools/packages/version-tools/src/test/tsconfig.json index cafb913ae554..de0d7af1e8fb 100644 --- a/build-tools/packages/version-tools/src/test/tsconfig.json +++ b/build-tools/packages/version-tools/src/test/tsconfig.json @@ -8,6 +8,7 @@ "outDir": "../../lib/test", "types": ["node", "mocha", "chai"], "skipLibCheck": true, + "exactOptionalPropertyTypes": true, }, "include": ["./**/*"], "references": [ diff --git a/build-tools/packages/version-tools/tsconfig.inexactOptionalPropertyTypes.json b/build-tools/packages/version-tools/tsconfig.inexactOptionalPropertyTypes.json new file mode 100644 index 000000000000..2ebd7d4dc5a1 --- /dev/null +++ b/build-tools/packages/version-tools/tsconfig.inexactOptionalPropertyTypes.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "exactOptionalPropertyTypes": false, + "skipLibCheck": true, + }, +} diff --git a/build-tools/packages/version-tools/tsconfig.json b/build-tools/packages/version-tools/tsconfig.json index 5be1b96ce6d0..05d57115a364 100644 --- a/build-tools/packages/version-tools/tsconfig.json +++ b/build-tools/packages/version-tools/tsconfig.json @@ -6,6 +6,7 @@ "outDir": "./lib", "types": ["node"], "noImplicitAny": true, + "exactOptionalPropertyTypes": true, }, "include": ["src/**/*"], "exclude": ["src/test/**/*"], diff --git a/fluidBuild.config.cjs b/fluidBuild.config.cjs index 9ebb912d94e5..a2075385bb51 100644 --- a/fluidBuild.config.cjs +++ b/fluidBuild.config.cjs @@ -80,7 +80,14 @@ module.exports = { script: false, }, "lint": { - dependsOn: ["eslint", "good-fences", "depcruise", "check:exports", "check:release-tags"], + dependsOn: [ + "check:inexactOptionalPropertyTypes", + "eslint", + "good-fences", + "depcruise", + "check:exports", + "check:release-tags", + ], script: false, }, "checks": { @@ -165,6 +172,7 @@ module.exports = { // therefore we need to require both before running api-extractor. "check:release-tags": ["tsc", "build:esnext"], "check:are-the-types-wrong": ["tsc", "build:esnext", "api"], + "check:inexactOptionalPropertyTypes": ["^build:esnext", "^api-extractor:esnext"], "check:format": { dependencies: [], script: true,