Migrate Electron app from JavaScript to TypeScript #140
+1,097
−17
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds TypeScript tooling and migrates main process and core utility modules to provide type safety for IPC boundaries, Electron APIs, and image processing operations.
Changes
Tooling & Build
allowJs: truefor incremental migrationdist/, updated main entry point and Electron Builder config@types/electron@1.4.38, using Electron 37's built-in types insteadType Definitions
types/ipc.tsFile Migrations (JS → TS)
main.ts: Typed Electron APIs (IpcMainEvent, BrowserWindow, MenuItemConstructorOptions)core/pix.ts: Typed PIX format with Sharp library interfaces, fixed channels type constraintutils/ipc_bridge.ts: Generic IPC forwarder with typed handlersfeatures/image_mode.ts: Converted to enum with typed mode manager classKey Technical Details
Sharp library type fix:
All TypeScript files compile to CommonJS in
dist/maintaining compatibility with existing JS modules. Remaining files continue to work viaallowJs: trueand can be migrated incrementally.Original prompt
This section details on the original issue you should resolve
<issue_title>Migration to typescript</issue_title>
<issue_description>Summary
Migrate Pegasus Electron app from JavaScript to TypeScript incrementally to improve type safety, DX, and maintainability while minimizing disruption.
Motivation
Strong typing for IPC contracts and render/main boundaries.
Catch runtime errors earlier; safer refactors as features grow.
Improve discoverability with IDE tooling and types.
Scope
Add TypeScript toolchain and config.
Compile to dist and point Electron to compiled outputs.
Incremental file-by-file migration with allowJs.
Provide type definitions for Electron, Node, and frequently used libs.
Keep current security model (no preload refactor yet).
Out of Scope
Security model changes (e.g., contextIsolation: true, preload API).
Large architectural changes or bundler switch.
Test framework introduction.
Plan
Phase 1: Tooling + Build
Phase 2: Type-safe IPC contracts
Phase 3: Core + Utils migration
Phase 4: Main/Renderer migration per panel
Phase 5: Strict mode tightening and cleanup
Tasks
Tooling
Add TypeScript: npm i -D typescript @types/node @types/electron
Add tsconfig.json with outDir: dist, rootDir aligned to repo, allowJs: true, resolveJsonModule: true.
Update package.json:
main → dist/main.js
Scripts: build:ts, watch:ts, dev (tsc watch + electron)
Build Pathing
Ensure assets and pages resolve correctly from compiled output.
Verify Electron Builder targets use compiled dist/main.js.
IPC Types
Centralize IPC channel names in a shared type module (e.g., types/ipc.ts).
Type IPCBridge methods and payloads.
Incremental Migration
Core: pix.js → core/pix.ts, image_layer.js → image_layer.ts, image_renderer.js → image_renderer.ts
Utils: ipc_bridge.js → utils/ipc_bridge.ts
Features: image_mode.js → features/image_mode.ts (enum + class typing)
Processing: image_processor.js → processing/image_processor.ts (define image buffers/types)
Main: main.js → main.ts (Electron types, IPC handlers)
Renderer: renderer/*.js per panel → .ts (DOM and IPC typing)
Config Tweaks
Add paths aliases if needed; ensure relative imports still resolve after build.
Add ESLint with TS plugin optionally for consistency.
CI/Build
Ensure CI runs npm run build:ts before packaging.
Verify Windows packaging still picks compiled files.
Acceptance Criteria
npm run dev launches the app via compiled dist/main.js.
All existing features work (open/save, panels, filters, paint, rotate, crop, analysis).
No console TS errors; baseline noImplicitAny tolerated initially.
IPC channels and payloads typed in a shared module and used on both sides.
Packaging succeeds and launches on Windows.
Risks & Mitigations
Path/asset resolution from dist: keep relative loadFile paths stable; adjust __dirname usage or copy assets.
Third-party types missing: add minimal ambient typings as needed.
Large diff: migrate per-folder, merge behind feature branch typescript, frequent small PRs.
Milestones
M1: Tooling + main.ts compiles/runs.
M2: Core + Utils migrated.
M3: IPC typed + 2 key renderers migrated (resize, filter).
M4: Remaining renderers migrated.
M5: Enable stricter TS options (noImplicitAny, strictNullChecks).
Try It (local)
Install
npm i -D typescript @types/node @types/electron
Scripts (example)
build:ts: tsc -p tsconfig.json
watch:ts: tsc -w -p tsconfig.json
dev: run npm run watch:ts and electron . (main points to dist/main.js)
Not...
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.