The published permissionless@0.3.6 npm package includes raw .ts source files (including .test.ts files) alongside the compiled _cjs, _esm, and _types directories. When a consumer project runs tsc --noEmit with strict: true, TypeScript resolves these .ts files and surfaces 19 upstream type errors that exist within the library's own source code.
While the package.json correctly declares "types": "./_types/index.d.ts" and the exports map points to _types/*.d.ts + _esm/*.js + _cjs/*.js, TypeScript still picks up the co-located raw .ts files during type-checking.
Reproduction
1. Create a minimal project:
mkdir permissionless-repro && cd permissionless-repro
npm init -y
npm install permissionless@0.3.6 viem@2.51.3
2. Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "esnext",
"moduleResolution": "bundler",
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"skipLibCheck": false
},
"include": ["index.ts"]
}
3. Create index.ts:
import { toSafeSmartAccount } from 'permissionless/accounts';
import { createSmartAccountClient } from 'permissionless';
console.log(toSafeSmartAccount, createSmartAccountClient);
4. Run type-check:
Expected Behavior
tsc --noEmit should complete with 0 errors, since the package.json exports map correctly points to pre-compiled .d.ts declarations.
Actual Behavior
19 type errors from within the library's own source files:
node_modules/permissionless/accounts/biconomy/toBiconomySmartAccount.ts(292,25): error TS2322: Type '`0x${string}` | undefined' is not assignable to type '`0x${string}`'.
node_modules/permissionless/accounts/biconomy/toBiconomySmartAccount.ts(293,25): error TS2322: Type 'bigint | undefined' is not assignable to type 'bigint'.
node_modules/permissionless/accounts/safe/signUserOperation.ts(108,13): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
node_modules/permissionless/accounts/safe/toSafeSmartAccount.ts(914,17): error TS2532: Object is possibly 'undefined'.
node_modules/permissionless/accounts/safe/toSafeSmartAccount.ts(915,17): error TS2532: Object is possibly 'undefined'.
... (19 total, spanning biconomy, kernel, light, safe, simple, thirdweb, trust accounts)
Root Cause
The published npm tarball includes raw .ts and .test.ts files at the package root level:
permissionless/
├── accounts/
│ ├── index.ts ← raw source (should not be published)
│ ├── decodeCalls.test.ts ← test file (should not be published)
│ └── safe/
│ ├── toSafeSmartAccount.ts ← raw source
│ └── signUserOperation.ts ← raw source
├── _cjs/ ← compiled (correct)
├── _esm/ ← compiled (correct)
├── _types/ ← declarations (correct)
└── package.json
TypeScript resolves these .ts files during type-checking even when skipLibCheck: false is set, because skipLibCheck only affects .d.ts files — not .ts source files in node_modules.
Suggested Fix
Exclude raw .ts source files from the published npm package by updating the files field in package.json:
{
"files": [
"_cjs",
"_esm",
"_types",
"package.json",
"README.md",
"LICENSE"
]
}
Or add .ts patterns to .npmignore:
# Exclude raw sources — only ship compiled output
*.ts
!*.d.ts
*.test.ts
Workarounds
Consumers can use either of these workarounds:
skipLibCheck: true in tsconfig.json — disables type-checking of all .d.ts (but also suppresses legitimate errors from other libraries)
- Filter script — run
tsc --noEmit and filter out lines containing permissionless before checking exit code
- SWC compiler — use
swc for compilation (no type-checking) + filtered tsc for type-checking only
Environment
permissionless: 0.3.6
viem: 2.51.3
typescript: 5.9.3
- OS: Windows 11 / Node 24
- Package manager: pnpm 10.33.0
Related
The published
permissionless@0.3.6npm package includes raw.tssource files (including.test.tsfiles) alongside the compiled_cjs,_esm, and_typesdirectories. When a consumer project runstsc --noEmitwithstrict: true, TypeScript resolves these.tsfiles and surfaces 19 upstream type errors that exist within the library's own source code.While the
package.jsoncorrectly declares"types": "./_types/index.d.ts"and theexportsmap points to_types/*.d.ts+_esm/*.js+_cjs/*.js, TypeScript still picks up the co-located raw.tsfiles during type-checking.Reproduction
1. Create a minimal project:
2. Create
tsconfig.json:{ "compilerOptions": { "target": "ES2022", "module": "esnext", "moduleResolution": "bundler", "strict": true, "noEmit": true, "esModuleInterop": true, "skipLibCheck": false }, "include": ["index.ts"] }3. Create
index.ts:4. Run type-check:
Expected Behavior
tsc --noEmitshould complete with 0 errors, since thepackage.jsonexports map correctly points to pre-compiled.d.tsdeclarations.Actual Behavior
19 type errors from within the library's own source files:
Root Cause
The published npm tarball includes raw
.tsand.test.tsfiles at the package root level:TypeScript resolves these
.tsfiles during type-checking even whenskipLibCheck: falseis set, becauseskipLibCheckonly affects.d.tsfiles — not.tssource files innode_modules.Suggested Fix
Exclude raw
.tssource files from the published npm package by updating thefilesfield inpackage.json:{ "files": [ "_cjs", "_esm", "_types", "package.json", "README.md", "LICENSE" ] }Or add
.tspatterns to.npmignore:Workarounds
Consumers can use either of these workarounds:
skipLibCheck: trueintsconfig.json— disables type-checking of all.d.ts(but also suppresses legitimate errors from other libraries)tsc --noEmitand filter out lines containingpermissionlessbefore checking exit codeswcfor compilation (no type-checking) + filteredtscfor type-checking onlyEnvironment
permissionless: 0.3.6viem: 2.51.3typescript: 5.9.3Related
createSmartAccountClienttype-checking performance issue (related but different — about speed, not errors)