Skip to content

Regenerate the TypeScript types, and make every package's types compile for a TypeScript caller - #113

Merged
jwrosewell merged 5 commits into
rcfrom
fix/regenerate-types
Nov 14, 2026
Merged

jwrosewell merged 5 commits into
rcfrom
fix/regenerate-types

Conversation

@jwrosewell

@jwrosewell jwrosewell commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Each package publishes the types/*.d.ts files committed in this repository, and nothing writes them again before a package is packed. The readmes say that "Calling the generation step is manual for now" (device-detection/readme.md line 236 at a9a3bd2e). So the published types have fallen behind the code. With TypeScript 5.9.3, npm run tsc on rc at a9a3bd2 changes 23 of the committed files and writes one that was never committed, pipeline/fiftyone.pipeline.core/types/callbackUrl.d.ts (run 43580575276).

Among what the published types lack today:

  • five methods of DataFileUpdateService, being accessError, refreshDataFile, fail, unhandled and integrityFailed,
  • JSONBundlerElement.getSequence and DataFile.onUpdateComplete,
  • AUTO_UPDATE_TEMP_PATH_NOT_SET and AUTO_UPDATE_UNKNOWN_ERROR in AutoUpdateStatus,
  • the base class of GeoLocationCloud, which is a Cloud Engine in the code and a class with no base in the types, so its types offer none of a Cloud Engine's members,
  • the types of callbackUrl.js, which the core package packs,
  • the doc comments that changes on rc this week wrote, such as which web integration elements PipelineBuilder adds (#105) and that updateOnStart downloads a missing data file (#52).

pipeline/fiftyone.pipeline.cloudrequestengine/types/cloudHelpers.d.ts declares makeHTTPRequest for a cloudHelpers.js that the package no longer has, and nothing in the repository refers to it.

A TypeScript caller that imports fiftyone.devicedetection.cloud and checks type files, as tsc does unless skipLibCheck is set, gets an error before and after the types are written again.

device-detection/fiftyone.devicedetection.cloud/types/index.d.ts(3,54): error TS2307: Cannot find module '../fiftyone.devicedetection.cloud/hardwareProfileCloudEngine' or its corresponding type declarations.

The package's index.js requires its own hardwareProfileCloudEngine.js through ../fiftyone.devicedetection.cloud/ (line 26 at a9a3bd2e), and tsc writes the same path into the types, where it points outside the types folder at a file with no types. The on-premise package's index.js requires swigHelpers.js the same way (line 27), which works only while the folder keeps its name, though tsc writes that type in full rather than as an import.

What changed

  1. The types are written again with npm run tsc and committed exactly as tsc wrote them, 23 files changed and callbackUrl.d.ts added.
  2. cloudHelpers.d.ts is removed.
  3. The two index.js files require their own files through ./, and the cloud package's types/index.d.ts is written again by tsc, which now imports ./hardwareProfileCloudEngine. These two lines are the only change to code.
  4. A new test, ci/tests/typesCompile.test.js, compiles a file that imports every package with types by its package name, with TypeScript's own API and the type files checked, and fails on any error. It runs among the unit tests of every build.

One type becomes more exact. HardwareProfileCloudEngine from the cloud package, which a caller that skips checking type files got as any because its import could not be found, now has its real type, so such a caller's use of it is now checked. Evidence.keys goes from {} to any and CloudRequestEngine.discovery from Promise<any> to any, both wider. Every other change adds a member, moves one within its file, writes the same type another way, as FlowElement.evidenceKeyFilter does, or changes a comment.

What tsc leaves out, and why no member is lost

  • CloudRequestEngine.isCacheable, getInternalIgnoringCase on ElementDataDictionary and AspectDataDictionary, and GeoLocationCloud.dataKey are no longer written in those classes' own files. TypeScript leaves a member out of a subclass's types when its type, and whether it is read-only or optional, match the base class's member (checker.ts lines 10761 to 10768 at TypeScript 5.9.3). Each is still declared on the base class, isCacheable in engine.d.ts line 48, getInternalIgnoringCase in elementData.d.ts line 39 and dataKey in flowElement.d.ts line 38, so a caller still sees it. What goes is the subclass's own doc comment.
  • The @deprecated notes on five test constants leave the two shared packages' testConstants types. These are envVars.licenseKeyEnvVar and legacyEnvVars in fiftyone.devicedetection.shared, and envVars.superResourceKeyEnvVar, ipiResourceKeyEnvVar and licenseKeyEnvVar in fiftyone.ipintelligence.shared. The notes stay in the code (device-detection/fiftyone.devicedetection.shared/lib/testConstants.js lines 37 and 43, ip-intelligence/fiftyone.ipintelligence.shared/lib/testConstants.js lines 29, 35 and 40), and the constants themselves stay in the types. A throwaway run, 43581251325, wrote the types of five small files on TypeScript 5.4.5 and 5.9.3. Neither version writes a @deprecated note for a property of an object literal, however the object is exported, and both write one only for a property set in a class. So the notes in the committed types had been written by hand, and keeping them would mean committing types that tsc does not write.

Tests

Whether the committed types are what npm run tsc writes. A throwaway workflow, not part of this draft, runs npm install and npm run tsc on Ubuntu with Node.js 24, adds every .d.ts file, new ones included, and uploads the difference from the commit.

Whether the types compile for a TypeScript caller. typesCompile.test.js ran on its own in a throwaway workflow on Ubuntu and Windows with Node.js 24, after ESLint passed on it.

Before the test was written, a throwaway run, 43584689955, compiled the TypeScript example gettingStarted.ts and the same import of every package with tsc --noEmit, once on rc at a9a3bd2 and once on e422e2d. The example compiled with no error on both, and the import gave the one error above on both, so writing the types again broke nothing the example uses and fixed nothing on its own.

Full build

Run 43585933895 on tmp/pr-matrix-113b, started by tools/pr-matrix.py without macOS. All 7 Setting 'PullRequestSha' lines give this head, a8b05e9, and Configure printed "Left out 2 macOS entries". Each of the six Build and Test jobs, Ubuntu, Ubuntu ARM and Windows on Node.js 22 and 24, passed 1,487 unit tests with 2 skipped, typesCompile.test.js among them, and every integration test it ran, with 4 skipped.

Each job merges rc as it is when the job starts, and #112 merged into rc at 10:36 UTC while the build ran. The Ubuntu and Windows jobs on Node.js 22 merged rc before #112 and ran 155 integration tests. The other four merged it with #112, which moves webIntegrationElements.test.js to the unit tests as webElements.test.js, and ran 100, the 55 in that file being the difference.

The earlier full build at e422e2d, before the test and the require change, run 43580961614, was green in the same way. ci/tests/environmentVariableNames.test.js reads every text file, the types included, for environment variable names, and ci/tests/corePackageFiles.test.js checks that the core package packs types/index.d.ts, and both passed in each job.

macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main.

What remains

  1. A check in the pull request build that fails when the committed types differ from what npm run tsc writes, #127. It is left for after this release, because each draft still open that changes code tsc reads would first need its types written again.
  2. Whichever draft that changes code tsc reads merges after this one should run npm run tsc and commit what it writes. #107 has merged into rc since this body was first written, and because the 51Did package now requires its OWID submodule, tsc also writes pipeline/fiftyone.pipeline.did/types/owid-js/v1.d.ts. Whether that file is committed is point 3 of Fail the pull request build when the committed TypeScript types differ from what tsc writes #127.

npm run tsc on rc changes 23 committed type files and writes one new
one, callbackUrl.d.ts, so the types published with each package match
what the code now offers. Members tsc leaves out of a subclass, such as
CloudRequestEngine.isCacheable, are still declared on the base class
with the same type.
Nothing in the repository has a cloudHelpers.js or refers to
cloudHelpers, so the file declared a module the package does not hold.
The test compiles, with TypeScript's own API, a file that imports each
package with types by its package name, and checks the type files as
well. It fails on fiftyone.devicedetection.cloud, whose types import
../fiftyone.devicedetection.cloud/hardwareProfileCloudEngine, which a
caller's compiler cannot find.
Two package entry points required a file of their own through
../<their folder>/, which works only while the folder has that name.
The cloud package's types then imported the same path from the types
folder, where a TypeScript caller cannot find it.
With the require changed, tsc writes the import as ./hardwareProfileCloudEngine.
@jwrosewell jwrosewell changed the title Regenerate the TypeScript types so the published types match the code Regenerate the TypeScript types, and make every package's types compile for a TypeScript caller Nov 14, 2026
@jwrosewell
jwrosewell marked this pull request as ready for review November 14, 2026 23:04
@jwrosewell
jwrosewell merged commit f2642f8 into rc Nov 14, 2026
4 checks passed
@jwrosewell
jwrosewell deleted the fix/regenerate-types branch November 14, 2026 23:04
@jwrosewell jwrosewell mentioned this pull request Nov 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant