Skip to content

ts split#29211

Merged
chrisnojima merged 28 commits into
nojima/HOTPOT-next-670-clean-2from
nojima/HOTPOT-ts-split
May 17, 2026
Merged

ts split#29211
chrisnojima merged 28 commits into
nojima/HOTPOT-next-670-clean-2from
nojima/HOTPOT-ts-split

Conversation

@chrisnojima
Copy link
Copy Markdown
Contributor

@chrisnojima chrisnojima commented May 15, 2026

Summary

Replaces the single shared/tsconfig.json with per-platform configs so that dom APIs are forbidden in native code and native-only APIs are forbidden in desktop code.

  • tsconfig.base.json — platform-agnostic compiler options (strict, noEmit, etc.)
  • tsconfig.desktop.json — adds dom lib + webpack-env types, excludes *.native.* / *.android.* / *.ios.* files
  • tsconfig.native.json — no dom, excludes *.desktop.* and the entire ./desktop/ directory
  • tsconfig.json — now just { "extends": "./tsconfig.desktop.json" } as editor fallback
  • tools/gen-ts-paths.mjs — scans shared/ for platform-split modules (files with .desktop.tsx/.native.tsx but no plain .tsx) and writes tsconfig.paths.desktop.json + tsconfig.paths.native.json so @/foo imports resolve to the right platform file
  • yarn tsc — now regenerates paths then checks both platform configs; both pass at 0 errors

Also fixes ~15 source files where native-specific type errors were surfaced by the stricter native config (DOM globals used in shared/native files, Timeout vs number, ResizeObserver in a .native.tsx, etc.).

and then

Summary

Replaces the generated per-file tsconfig.paths.*.json mappings with TypeScript's built-in moduleSuffixes option, and splits the
single tsconfig.json into proper per-platform configs.

Before: yarn tsc ran a gen-ts-paths.mjs script that scanned for .desktop.tsx/.native.tsx files and emitted ~160 explicit @/foo →
./foo.desktop path mappings. Any platform-split module not in that list resolved to an untyped .d.ts stub (covered by
skipLibCheck).

After: yarn tsc runs tsgo directly against two configs. TypeScript's moduleSuffixes handles suffix resolution automatically —
import from '@/foo' tries foo.desktop.tsx before foo.tsx on desktop, and foo.native.tsx before foo.tsx on native. No generated
files, no stubs.

Config changes

┌─────────────────────────┬───────────────────────────────────────────────────────────────────────────────┐
│ File │ Role │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ tsconfig.base.json │ Strict options shared by both platforms │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ tsconfig.desktop.json │ Adds dom + webpack-env, excludes .native., moduleSuffixes: [".desktop", ""] │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ tsconfig.native.json │ No dom, excludes .desktop. + ./desktop/, moduleSuffixes: [".native", ""] │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ tsconfig.json │ Extends desktop — editor/IDE fallback only │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ tsconfig.paths..json │ Simplified to just { "@/": ["./*"] } — no per-file mappings │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ package.json tsc script │ Drops the gen-ts-paths.mjs step │
└─────────────────────────┴───────────────────────────────────────────────────────────────────────────────┘

tools/gen-ts-paths.mjs is kept on disk as documentation of the old approach.

Source fixes (307 files, ~1700 insertions / ~1250 deletions)

.d.ts stub replacement: ~25 .d.ts stubs that previously bridged cross-platform type gaps were replaced with proper .shared.tsx
barrel files that re-export types explicitly. Platform .desktop.tsx/.native.tsx files that imported from the stub path were
updated to import from .shared.

Circular import fixes: With moduleSuffixes, import from './foo' in foo.native.tsx resolves to itself. Fixed by changing to import
from './foo.shared' in affected .native.tsx files.

Explicit suffix import fixes: import from '@/router-v2/screen-layout.desktop' in a shared file causes the native compiler to look
for screen-layout.desktop.native.tsx, then fall back to the desktop file. Fixed by dropping the explicit suffix and letting
moduleSuffixes resolve.

Native type strictness fixes: The native config has no dom lib. Surfaced issues fixed:

  • window.console.log → console.log directly in local-debug.native.tsx
  • window.requestIdleCallback narrowing in util/idle-callback.tsx (IIFE approach)
  • ScrollViewRef via useImperativeHandle in common-adapters/scroll-view.native.tsx
  • File/DataTransfer interface stubs in globals.native.d.ts
  • process['type'] bracket notation for noPropertyAccessFromIndexSignature

Platform constant widening: With moduleSuffixes, ESLint now resolves isMobile, isDarwin, isElectron, etc. to their
platform-specific literal values, triggering no-unnecessary-condition in shared files. Fixed by annotating constants as : boolean
/ : string rather than letting them infer as literal types.

Promise/async fixes in desktop files: Properly resolved types exposed floating promises in .desktop.tsx event handlers. Fixed
with void expression pattern.

…red modules

Task 6 deleted .d.ts files that are still needed for relative imports within
the same package (e.g. `import {Box2} from './box'` in common-adapters files).
The tsconfig paths mappings only intercept `@/*` imports, not relative ones.

Restore all 107 deleted .d.ts stubs. Update gen-ts-paths.mjs to skip emitting
a path entry when a plain .d.ts already exists (avoiding redundant and
conflicting @/foo/index → foo/index.platform entries). Also add bare-directory
path entries (e.g. @/foo → foo/index.platform) for directories that have only
platform-split index files and no index.d.ts.

Result: desktop 0 errors (was 421), native 47 errors (was 450, all pre-existing).
Add globals.native.d.ts to properly declare platform-specific globals
(window, location) instead of using `global as {window?: ...}` casts
throughout the codebase.

Also: split make-icons.page to .desktop/.native, fix DataTransfer
augmentation in globals.d.ts for tsgo compatibility, update ESLint to
use per-platform tsconfigs (native-first) so shared files are
type-checked with native types.
Fragment containing only the IconMeta type with no importers; the type
is already defined in icon.constants-gen.shared.tsx.
@chrisnojima chrisnojima merged commit f0165a6 into nojima/HOTPOT-next-670-clean-2 May 17, 2026
@chrisnojima chrisnojima deleted the nojima/HOTPOT-ts-split branch May 17, 2026 00:10
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