[hotwired__turbo] Align types with the v8.0.23 implementation#75208
[hotwired__turbo] Align types with the v8.0.23 implementation#75208myabc wants to merge 4 commits into
Conversation
Audited against hotwired/turbo v8.0.23 source and built dist export surface. Event details: - turbo:before-render: drop isPreview (not in the dispatched detail); turbo:render: add renderMethod detail; turbo:before-frame-render: add renderMethod; turbo:reload: type the reason/context detail - VisitFallback: make options parameter optional Fetch layer: - FetchRequest: declare constructor (with FetchRequestDelegate), split method accessors (reads back UPPERCASE, assignments take lowercase verbs), add abortController/abortSignal, entries, isSafe, location, defaultHeaders, cancel(), perform(), acceptResponseType() - FetchResponse: declare constructor; header() and contentType return string | null; responseHTML resolves string | undefined; mark getter-backed members readonly - FormSubmission#method: string (reads back UPPERCASE) Missing exports now declared: fetch, FetchMethod, FetchEnctype, fetchMethodFromString, fetchEnctypeFromString, isSafe, FrameLoadingStyle, PageRenderer, FrameRenderer, PageSnapshot, setProgressBarDelay, setConfirmMethod (both deprecated) Cleanups: - StreamElement attribute getters (action, target, targets, requestId) are string | null - visit() and Turbo.visit() accept URL as well as string - TurboGlobal.registerAdapter takes Adapter (was unknown); Turbo.setConfirmMethod matches config.forms.confirm signature - config.forms.confirm may return boolean | Promise<boolean> (implementation awaits the result)
|
@myabc Thank you for submitting this PR! This is a live comment that I will keep updated. 1 package in this PRCode ReviewsBecause you edited one package and updated the tests (👏), I can help you merge this PR once someone else signs off on it. You can test the changes of this PR in the Playground. Status
Once every item on this list is checked, I'll ask you for permission to merge and publish the changes. Diagnostic Information: What the bot saw about this PR{
"type": "info",
"now": "-",
"pr_number": 75208,
"author": "myabc",
"headCommitOid": "4809e8b00626bc150a319c896df8ca73675cf27e",
"mergeBaseOid": "e2580e07bfb619bbaa80a31c6e9d0e2ec35fea22",
"lastPushDate": "2026-07-04T16:52:32.000Z",
"lastActivityDate": "2026-07-04T16:52:32.000Z",
"hasMergeConflict": false,
"isFirstContribution": false,
"tooManyFiles": false,
"hugeChange": false,
"tooManyCommits": false,
"tooManyReviews": false,
"popularityLevel": "Popular",
"pkgInfo": [
{
"name": "hotwired__turbo",
"kind": "edit",
"files": [
{
"path": "types/hotwired__turbo/hotwired__turbo-tests.ts",
"kind": "test"
},
{
"path": "types/hotwired__turbo/index.d.ts",
"kind": "definition"
}
],
"owners": [
"G-Rath",
"lukeify",
"myabc"
],
"addedOwners": [],
"deletedOwners": [],
"popularityLevel": "Popular"
}
],
"reviews": [],
"mainBotCommentID": 4883127195,
"ciResult": "pass"
} |
|
🔔 @G-Rath @lukeify — please review this PR in the next few days. Be sure to explicitly select |
There was a problem hiding this comment.
Pull request overview
Updates the @hotwired/turbo type declarations to better match the Turbo v8.0.23 runtime export surface and behavior (notably events, fetch layer, and additional exported symbols), along with expanded DTS tests to validate the new typings.
Changes:
- Added typings for previously-missing runtime exports (e.g.
fetch,FetchMethod,FetchEnctype,FrameLoadingStyle,PageRenderer,FrameRenderer,PageSnapshot, and deprecated module-level setters). - Aligned fetch-layer and event typings with v8.0.23 behavior (e.g.
FetchRequest/FetchResponseconstructors & members, eventdetailpayloads,VisitFallbackoptions optionality, andvisit()acceptingURL). - Updated tests to exercise the new exports and refined types (including new event/detail expectations and readonly/getter-backed members).
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| types/hotwired__turbo/index.d.ts | Aligns exported types and event/fetch APIs with Turbo v8.0.23 and adds typings for additional runtime exports. |
| types/hotwired__turbo/hotwired__turbo-tests.ts | Extends the DTS test suite to cover new exports and updated type expectations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
StreamMessage and BrowserAdapter were declared as exported classes, but @hotwired/turbo does not export either at runtime (neither appears in the dist export surface), so value imports compiled but resolved to undefined. Introduced in DefinitelyTyped#74439. Convert both to interfaces: StreamMessage keeps its instance shape (fragment) for renderStreamMessage(); BrowserAdapter now extends Adapter, keeping progressBar and the members it makes non-optional. Tests assert both names are no longer usable as values. Fixes DefinitelyTyped#75207
Model FetchRequest#method and FormSubmission#method as getter/setter
pairs: reads return uppercase verbs, assignments accept Turbo's
lowercase method names, matching the implementation. Narrow
FetchRequest#fetchOptions.method to the uppercase verbs the request
actually stores.
Keep the new RequestMethod union as an internal helper (with
`export {}`) since Turbo does not export it; tests assert it stays
unexported.
Declare PageView and SnapshotCache interfaces and expose session.view, verified against hotwired/turbo v8.0.23. Downstream code needs view.lastRenderedLocation when rewriting the URL through session.history, so the snapshot cache and page-refresh detection stay keyed to the rendered location. Both are type-only declarations (Turbo does not export the classes at runtime), following the existing BrowserAdapter/StreamMessage convention; tests assert they are not constructible.
🤖 Drafted with agent assistance.
Please fill in this template.
pnpm test <package to test>.If changing an existing definition:
Result of auditing these declarations against the hotwired/turbo v8.0.23 source and the built
dist/turbo.es2017-esm.jsexport surface.Fixes #75207:
StreamMessageandBrowserAdapterwere declared as exported classes, but@hotwired/turboexports neither at runtime, so value imports compiled and then resolved toundefined(introduced in #74439). Both are now interfaces; tests assert the names are unusable as values. Technically breaking for anyone value-importing them, but that code was already broken at runtime.Event details
turbo:before-render: removedisPreview— not part of the dispatched detail (view.js:72);turbo:renderandturbo:before-frame-render: addedrenderMethod;turbo:reload: typed the{ reason, context? }detail.VisitFallback:optionsis now optional — theturbo:frame-missingfallback can be called asdetail.visit(url).Fetch layer
FetchRequest: declared the real constructor (introducingFetchRequestDelegate) so zero-argnew FetchRequest()no longer compiles; addedabortController,abortSignal,entries,isSafe,location,defaultHeaders,cancel(),perform(),acceptResponseType().FetchRequest#methodandFormSubmission#methoduse split accessors: the getters return the UPPERCASE verbs the implementation stores (method.toUpperCase()), the setters keep accepting Turbo's lowercase verbs, andFetchRequest#fetchOptions.methodis narrowed to the uppercase verbs so the getter is sound. The lowercase union is an internalRequestMethodhelper — not exported, matching Turbo, with a test asserting that.FetchResponse: declared the constructor;header()andcontentTypearestring | null(delegating toHeaders#get);responseHTMLresolvesstring | undefined; getter-backed members are nowreadonly.Previously missing runtime exports
Now declared:
fetch(Turbo'sX-Turbo-Request-Id-appending wrapper),FetchMethod,FetchEnctype,fetchMethodFromString,fetchEnctypeFromString,isSafe,FrameLoadingStyle,PageRenderer,FrameRenderer,PageSnapshot(minimal statics + getters), and the deprecatedsetProgressBarDelay/setConfirmMethod.session.viewAdds
TurboSession#view, typed via newPageViewandSnapshotCacheinterfaces (lastRenderedLocation,snapshot,snapshotCache,cacheSnapshot(), …), verified against page_view.js / snapshot_cache.js. Both are type-only, per the same non-runtime-export convention. Motivated by downstream code that must correctview.lastRenderedLocation(it keys the snapshot cache and page-refresh detection) after rewriting the URL throughsession.history: opf/openproject#23818 (comment).Cleanups / judgment calls
StreamElementattribute getters (action,target,targets,requestId) arestring | null— readonly reflections of attributes genuinely absent in common cases (request-idin particular), so unlike the write-siderefreshdiscussion in [hotwired__turbo] Add nullable FrameElement.refresh #75196 thenullis observable. Happy to revert if we'd rather idealize here too.visit()/Turbo.visit()acceptURLas well asstring;Turbo.registerAdaptertakesAdapter(wasunknown);Turbo.setConfirmMethodmatchesconfig.forms.confirm, which may returnboolean | Promise<boolean>(the implementationawaits it, soconfig.forms.confirm = window.confirmtype-checks).Not included (deliberate non-alignments, per #75196):
FrameElement.refreshstays"morph" | null;VisitOptionsstays the documented{ action?, frame? };FetchResponse.isHTMLstaysbooleaneven though the implementation returns a truthy match result (upstream fix candidate);TurboSubmitEndEvent.successstays required even though an aborted submission dispatches without a result.