Skip to content

adapter-cloudflare: the runtime types from wrangler types merge with lib.dom's Element, so HTMLSelectElement is no longer assignable to HTMLElement #17372

Description

@imlargo

Describe the bug

The adapter docs say to run wrangler types so that platform can be typed, and the sv template puts the generated worker-configuration.d.ts in compilerOptions.types. That file declares the HTMLRewriter API as global interfaces, among them:

interface Element {
    tagName: string;
    // ...
    remove(): Element;
    // ...
}

$app/tsconfig sets lib: ["esnext", "DOM", "DOM.Iterable"], so this declaration merges with lib.dom's Element. lib.dom's HTMLSelectElement overrides remove as remove(index?: number): void; after the merge, Element.remove also has the (): Element signature, and the override no longer satisfies it:

Type 'HTMLSelectElement' is not assignable to type 'HTMLElement'.
  The types returned by 'remove()' are incompatible between these types.
    Type 'void' is not assignable to type 'Element'.

In practice: any bind:this from a <select> into an HTMLElement | null fails svelte-check. shadcn-svelte's native-select does exactly that, so sv create with the Cloudflare adapter plus shadcn-svelte add native-select does not pass pnpm check.

Cloudflare treats the overlap as intended. In cloudflare/workers-sdk#10108 a maintainer wrote that "Cloudflare Workers types are intentionally designed to be used independently from DOM types, not alongside them" and closed the issue. The setup the adapter docs and the sv template produce is that combination, which is why I am filing this here rather than there.

Reproduction

No SvelteKit needed; the clash is between lib.dom and the generated file:

mkdir repro && cd repro && npm init -y && npm i -D typescript wrangler
echo '{ "name": "repro", "main": "worker.js", "compatibility_date": "2026-10-05" }' > wrangler.jsonc
npx wrangler types
echo 'const el: HTMLElement = document.createElement("select");' > repro.ts
npx tsc --noEmit --strict --lib es2022,dom --skipLibCheck repro.ts worker-configuration.d.ts

The same tsc call without worker-configuration.d.ts passes.

In a SvelteKit project:

npx sv@1.1.0 create --template minimal --types ts --add sveltekit-adapter="adapter:cloudflare+cfTarget:workers" --install npm repro
cd repro && npx wrangler types
cat > src/lib/Select.svelte <<'SVELTE'
<script lang="ts">
	let ref: HTMLElement | null = $state(null);
</script>

<select bind:this={ref}></select>
SVELTE
npm run check

Logs

Error: Type 'HTMLSelectElement' is not assignable to type 'HTMLElement'.
  The types returned by 'remove()' are incompatible between these types.
    Type 'void' is not assignable to type 'Element'. (ts)
	<select
		bind:value
		bind:this={ref}

Same result with TypeScript 5.9 and 6.0.3.

System Info

  System:
    OS: Linux 7.0 Ubuntu 26.04.1 LTS
  Binaries:
    Node: 24.21.0
    npm: 11.19.0
    pnpm: 11.10.0
  npmPackages:
    @sveltejs/adapter-cloudflare: ^8.0.0 => 8.0.0
    @sveltejs/kit: ^3.0.0 => 3.0.0
    @sveltejs/vite-plugin-svelte: ^7.2.0 => 7.3.1
    svelte: ^5.57.1 => 5.57.1
    svelte-check: ^4.6.0 => 4.7.6
    typescript: ^6.0.3 => 6.0.3
    vite: ^8.3.0 => 8.3.2
    wrangler: ^4.97.0 => 4.147.0 (runtime types from workerd 1.20261001.1)

Severity

serious, but I can work around it

Additional Information

wrangler types --include-runtime=false emits only the Env interface, which has no DOM overlap, but then Fetcher, ExecutionContext and IncomingRequestCfProperties are undefined and App.Platform cannot be typed the way the docs show. If the adapter shipped those few types itself, projects could generate Env only and keep lib.dom intact. Failing that, a note in the adapter docs that the runtime types and bind:this on form elements do not mix would save the next person the afternoon.

Activity

  1. svelte-triage-bot commented on Oct 7, 2026

    @svelte-triage-bot
    Contributor

    I reproduced the issue, but could not produce a safe, verified fix.

    What I tried

    Why I stopped
    The bug is reproducible, but a safe fix is not practical within this Kit checkout. The root cause is combining two ambient libraries that Cloudflare intentionally does not support together. Symptom patches such as augmenting Element.remove or relying on skipLibCheck leave many other Request, Headers, Response, stream, cache, WebSocket, and HTMLRewriter collisions. --include-runtime=false is safe for DOM types, but its generated Env references a large and changing set of Worker globals; preserving useful, compatibility-date-aware typing requires Cloudflare to provide an isolated/importable generated type surface, or requires a coordinated redesign of adapter typing and the sveltejs/cli template (which owns the reported generated tsconfig/App.Platform setup). Reverting Kit docs to hand-maintained selective bindings would be incomplete, while shipping a static alias list would drift from Wrangler configurations. No unverified patch was committed or pushed.

  2. added theissue type on Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions