TypeScript Compiler Crash with moduleResolution: "bundler"
Summary
The live_toast dependency causes a TypeScript compiler crash when imported in projects using moduleResolution: "bundler". The crash occurs with an internal TypeScript error: "Debug Failure. False expression" in the getConstructorDefinedThisAssignmentTypes function.
Environment
- TypeScript Version: 5.4.5 (also tested with 5.8.3)
- Node.js Version: v22.12.0
- Operating System: macOS 24.5.0
- live_toast Version: [version from deps/live_toast]
TypeScript Configuration
{
"compilerOptions": {
"target": "ES2020",
"lib": ["dom", "dom.iterable", "ES2020"],
"allowJs": true,
"skipLibCheck": true,
"types": ["vite/client"],
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "bundler",
"isolatedModules": true,
"resolveJsonModule": true,
"noEmit": true,
"jsx": "react"
}
}
Reproduction Steps
- Create a TypeScript project with
moduleResolution: "bundler"
- Import
createLiveToastHook from live_toast:
import { createLiveToastHook } from "../../deps/live_toast";
- Run TypeScript compilation:
npx tsc
Expected Behavior
TypeScript compilation should complete successfully.
Actual Behavior
TypeScript compiler crashes with the following error:
Error: Debug Failure. False expression.
at getConstructorDefinedThisAssignmentTypes (/path/to/node_modules/typescript/lib/tsc.js:52803:11)
at getWidenedTypeForAssignmentDeclaration (/path/to/node_modules/typescript/lib/tsc.js:52614:78)
at getTypeOfVariableOrParameterOrPropertyWorker (/path/to/node_modules/typescript/lib/tsc.js:53029:14)
at getTypeOfVariableOrParameterOrProperty (/path/to/node_modules/typescript/lib/tsc.js:52974:20)
at getTypeOfSymbol (/path/to/node_modules/typescript/lib/tsc.js:53306:14)
at getWriteTypeOfSymbol (/path/to/node_modules/typescript/lib/tsc.js:53284:29)
at checkPropertyAccessExpressionOrQualifiedName (/path/to/node_modules/typescript/lib/tsc.js:70818:116)
at checkPropertyAccessExpression (/path/to/node_modules/typescript/lib/tsc.js:70576:94)
at checkExpressionWorker (/path/to/node_modules/typescript/lib/tsc.js:76295:16)
at checkExpression (/path/to/node_modules/typescript/lib/tsc.js:76216:32)
Root Cause Analysis
The issue appears to be caused by the global interface extension in live_toast.ts:
declare global {
interface HTMLElement {
order: number
targetDestination: string
}
}
When TypeScript uses moduleResolution: "bundler", it encounters a bug in its type inference system when processing property access chains on these extended global interfaces, particularly in the context of constructor-defined property assignments.
Workarounds Attempted
- ✅ Skipping TypeScript compilation - Works but loses type checking benefits
- ❌ Using
@ts-ignore - Doesn't prevent the crash
- ❌ Excluding files with
exclude - Still processes imports
- ❌ Creating wrapper files - Still triggers the crash
- ❌ Custom type declarations - Doesn't resolve the internal compiler bug
Working Workaround
Currently, the only viable workaround is to skip TypeScript type checking in the build process:
{
"scripts": {
"build": "vite build" // instead of "tsc && vite build"
}
}
Suggested Fixes
-
Modify the global interface extension to use optional properties:
declare global {
interface HTMLElement {
order?: number;
targetDestination?: string;
}
}
-
Use a more specific interface instead of extending the global HTMLElement:
interface LiveToastElement extends HTMLElement {
order: number;
targetDestination: string;
}
-
Add a TypeScript configuration note in the documentation about moduleResolution compatibility
Additional Context
- The crash occurs specifically with
moduleResolution: "bundler"
- Works fine with
moduleResolution: "node"
- The issue is reproducible across different TypeScript versions (5.4.5 and 5.8.3)
- This affects Phoenix LiveView projects using modern TypeScript configurations
Impact
This issue prevents developers from using modern TypeScript configurations (moduleResolution: "bundler") with live_toast, forcing them to either:
- Use older module resolution strategies
- Skip type checking entirely
- Avoid using live_toast
Would appreciate any guidance on resolving this TypeScript compatibility issue!
TypeScript Compiler Crash with
moduleResolution: "bundler"Summary
The
live_toastdependency causes a TypeScript compiler crash when imported in projects usingmoduleResolution: "bundler". The crash occurs with an internal TypeScript error: "Debug Failure. False expression" in thegetConstructorDefinedThisAssignmentTypesfunction.Environment
TypeScript Configuration
{ "compilerOptions": { "target": "ES2020", "lib": ["dom", "dom.iterable", "ES2020"], "allowJs": true, "skipLibCheck": true, "types": ["vite/client"], "esModuleInterop": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "module": "esnext", "moduleResolution": "bundler", "isolatedModules": true, "resolveJsonModule": true, "noEmit": true, "jsx": "react" } }Reproduction Steps
moduleResolution: "bundler"createLiveToastHookfrom live_toast:npx tscExpected Behavior
TypeScript compilation should complete successfully.
Actual Behavior
TypeScript compiler crashes with the following error:
Root Cause Analysis
The issue appears to be caused by the global interface extension in
live_toast.ts:When TypeScript uses
moduleResolution: "bundler", it encounters a bug in its type inference system when processing property access chains on these extended global interfaces, particularly in the context of constructor-defined property assignments.Workarounds Attempted
@ts-ignore- Doesn't prevent the crashexclude- Still processes importsWorking Workaround
Currently, the only viable workaround is to skip TypeScript type checking in the build process:
{ "scripts": { "build": "vite build" // instead of "tsc && vite build" } }Suggested Fixes
Modify the global interface extension to use optional properties:
Use a more specific interface instead of extending the global HTMLElement:
Add a TypeScript configuration note in the documentation about moduleResolution compatibility
Additional Context
moduleResolution: "bundler"moduleResolution: "node"Impact
This issue prevents developers from using modern TypeScript configurations (
moduleResolution: "bundler") with live_toast, forcing them to either:Would appreciate any guidance on resolving this TypeScript compatibility issue!