[T3 Connect] TypeScript SDK: types for NodeNext and exactOptionalPropertyTypes consumers - #6009
Draft
bradleyshep wants to merge 1 commit into
Draft
bradleyshep wants to merge 1 commit into
bradleyshep wants to merge 1 commit into
Conversation
3 of 4 tasks
bradleyshep
force-pushed
the
bradley/ts-sdk-strict-consumers
branch
2 times, most recently
from
September 30, 2026 15:57
b0901aa to
02db3b5
Compare
3 of 4 tasks
bradleyshep
force-pushed
the
bradley/ts-sdk-strict-consumers
branch
from
September 30, 2026 17:38
02db3b5 to
c44434a
Compare
…opertyTypes consumers
The published .d.ts files re-export with extensionless relative paths
(`export * from './lib/connection_id'`). The package is `"type": "module"`,
so TypeScript projects using `moduleResolution: node16/nodenext` cannot
resolve them and see no exports from `spacetimedb` at all.
Separately, `ConstraintOpts` and `IndexOpts` declare `name?: string` while
the SDK derives `{ name: string | undefined }` for them. Under
`exactOptionalPropertyTypes` every generated schema then fails
`UntypedSchemaDef`, and `conn.reducers` collapses to `never`.
- Give every relative import in the SDK source an explicit extension; tsc
copies specifiers into the emitted .d.ts files verbatim. The moduledef and
client-api generators now emit the extension too.
- Widen the optional `name` fields to `string | undefined`.
- Lint rejects extensionless relative imports in the SDK source, and a
test typechecks generated bindings against the built package with
`exactOptionalPropertyTypes` on.
bradleyshep
force-pushed
the
bradley/ts-sdk-strict-consumers
branch
from
October 1, 2026 17:26
c44434a to
405f890
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description of Changes
The published type files don't work for two common strict TypeScript setups.
'./lib/identity'. The package is"type": "module", so NodeNext treats them as ESM and requires extensions; importingspacetimedbthen finds no exports at all (Module '"spacetimedb"' has no exported member 'DbConnectionBuilder').skipLibCheckdoesn't help. Every relative import in the SDK now has an explicit extension, which carries into the published.d.tsfiles. A lint rule keeps it that way, and codegen (regen-typescript-moduledef) andgenerate-client-apiemit extensions too.exactOptionalPropertyTypes. Built table schemas type constraint names asstring | undefined, butConstraintOptsandIndexOptsdeclarename?: string. Under the flag, every generated table fails the SDK's own constraint andconn.reducersbecomesnever. Both option types now declarename?: string | undefined.tests/consumertypechecks a small strict app against the built package, once with Bundler and once with NodeNext resolution, both withexactOptionalPropertyTypes, and assertstscexits 0.Split out of #6006.
API and ABI breaking changes
None. Relative import paths inside the package change; the public entry points and types don't.
Rollback safety impact
n/a
Expected complexity level and risk
Testing
pnpm buildandpnpm testincrates/bindings-typescript(324 passing), including both consumer caseseslintandprettier --checkspacetimedb,spacetimedb/server,spacetimedb/react) with TypeScript 4.9, 5.0, 5.4, 5.9 and 6.0, undernode(node10), Node16, NodeNext and Bundler resolution, withskipLibCheckon and off. No configuration that passed before fails after; 16 Node16/NodeNext configurations go from failing to passing. The.tspaths in the published.d.tsfiles resolve in every mode from TypeScript 5.0 up.spacetime generatefor users still import without extensions, so NodeNext consumers of their own generated code need a follow-up in the TypeScript codegen