Changelog - 2026-10-16
Restate the decorator options in your own tsconfig
Bug FixIn one line. Bun ignores "extends": "@venizia/dev-configs/tsconfig.common.json", so every tsconfig.json that Bun runs must restate two options itself.
json
{
"extends": "@venizia/dev-configs/tsconfig.common.json",
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false
}
}What changed
- The docs say it precisely. Bun 1.4.2 skips an
extendsthat names a package, even one level deep. Bun then compiles TC39 decorators:@injecton a constructor parameter is dropped with no error, and class fields get define semantics instead of the assign semantics of thetscbuild. - The trap is silent.
tscfollows the whole chain, so typecheck and build stay green. Onlybun runandbun testdiverge. - Every IGNIS package and example now restates both options. The published
distis byte-identical. The test suites now run the same class-field semantics as the code they ship.
extends | What Bun compiles |
|---|---|
@venizia/dev-configs/tsconfig.common.json | TC39 decorators - wrong |
@venizia/dev-configs/tsconfig.base.json | TC39 decorators - wrong |
the options restated in your own tsconfig.json | legacy decorators - right |
Who is affected
- An application or package that Bun runs and whose
tsconfig.jsononly extends dev-configs. Add"experimentalDecorators": trueand"useDefineForClassFields": falseto itscompilerOptions. - A project that already restates
experimentalDecorators. AdduseDefineForClassFields: falseso its tests run the class-field semantics it ships. emitDecoratorMetadata. Restate it only if your code readsdesign:*metadata. Under Bun it turns an interface-typed constructor parameter into a runtime import that fails withExport named 'X' not found, so import such names withimport type.tsc --noEmit --isolatedModulesreports most of them as TS1272; loading each package'ssrc/index.tsunder Bun finds the rest.