fix(workspace): point package "types" exports at src/, not stale dist/ (#496)

Each workspace package had its exports map pointing `types` at
`./dist/...d.ts` while `default` pointed at `./src/...ts`. The dist
directory is a build artifact only refreshed when someone runs
`pnpm build` in that package — meaning every other package in the
monorepo typechecks against last week's type signatures.

Concrete failure mode: contributor edits a function in
packages/shared/src/utils/foo.ts (changes a parameter type, adds a
new export, etc.), runs `pnpm typecheck` from root, sees green. The
check actually validated against the stale dist/.d.ts. Real type
errors stay invisible until CI builds shared first, by which point
the diff is already pushed.

Fix: point `types` at the same `src/` paths the runtime resolves to.
TypeScript reads .ts source as types fine when consumers share the
same TS version, which a monorepo guarantees. Verified end-to-end:
adding a new export to shared and immediately typechecking @kan/api
now picks it up without rebuilding shared, and breaking a return
type immediately fails the consumer's typecheck.

Applied to @kan/api, @kan/db, @kan/logger, @kan/shared.
@kan/email is intentionally left as-is because its source is .tsx
(JSX) — pointing types at .tsx would force every consumer to enable
--jsx in their tsconfig, which is a worse cascade than the stale
dist problem we're solving.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Meinhold
2026-05-17 07:55:07 +10:00
committed by GitHub
parent 711ff7f610
commit d9157b6218
4 changed files with 18 additions and 18 deletions

View File

@@ -5,35 +5,35 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"types": "./src/index.ts",
"default": "./src/index.ts"
},
"./root": {
"types": "./dist/root.d.ts",
"types": "./src/root.ts",
"default": "./src/root.ts"
},
"./trpc": {
"types": "./dist/trpc.d.ts",
"types": "./src/trpc.ts",
"default": "./src/trpc.ts"
},
"./types": {
"types": "./dist/types.d.ts",
"types": "./src/types/router.types.ts",
"default": "./src/types/router.types.ts"
},
"./openapi": {
"types": "./dist/openapi.d.ts",
"types": "./src/openapi.ts",
"default": "./src/openapi.ts"
},
"./utils/rateLimit": {
"types": "./dist/utils/rateLimit.d.ts",
"types": "./src/utils/rateLimit.ts",
"default": "./src/utils/rateLimit.ts"
},
"./utils/apiLogging": {
"types": "./dist/utils/apiLogging.d.ts",
"types": "./src/utils/apiLogging.ts",
"default": "./src/utils/apiLogging.ts"
},
"./utils/permissions": {
"types": "./dist/utils/permissions.d.ts",
"types": "./src/utils/permissions.ts",
"default": "./src/utils/permissions.ts"
}
},

View File

@@ -5,27 +5,27 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"types": "./src/index.ts",
"default": "./src/index.ts"
},
"./client": {
"types": "./dist/client.d.ts",
"types": "./src/client.ts",
"default": "./src/client.ts"
},
"./schema": {
"types": "./dist/schema.d.ts",
"types": "./src/schema/index.ts",
"default": "./src/schema/index.ts"
},
"./types/*": {
"types": "./dist/types/*.d.ts",
"types": "./src/types/*",
"default": "./src/types/*"
},
"./repository/*": {
"types": "./dist/repository/*.d.ts",
"types": "./src/repository/*.ts",
"default": "./src/repository/*.ts"
},
"./redis": {
"types": "./dist/redis.d.ts",
"types": "./src/redis.ts",
"default": "./src/redis.ts"
}
},

View File

@@ -5,7 +5,7 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},

View File

@@ -5,15 +5,15 @@
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"types": "./src/index.ts",
"default": "./src/index.ts"
},
"./utils": {
"types": "./dist/utils/index.d.ts",
"types": "./src/utils/index.ts",
"default": "./src/utils/index.ts"
},
"./constants": {
"types": "./dist/constants/index.d.ts",
"types": "./src/constants/index.ts",
"default": "./src/constants/index.ts"
}
},