How to fix Option 'declaration' cannot be used without 'emitDeclarationOnly' when 'noEmit' is set in TypeScript

TypeScriptINTERMEDIATEHIGHUpdated Dec 8, 2025ยท 175 views

This error occurs when TypeScript compiler options conflict in your tsconfig.json file. The declaration option requires either emitDeclarationOnly or a normal emit mode, but noEmit prevents all file emission. The fix involves choosing one option strategy and removing conflicting settings.

Quick fix

Fixes TS5053

{
  "compilerOptions": {
    "noEmit": true  // Pick ONE strategy - this disables ALL output
  }
}
  1. Identify your primary emit strategy
  2. Remove conflicting options from tsconfig.json
  3. Check for inherited configs in extends
  4. For monorepo/workspace setups, use separate configs
typescript โ€” error
{
"compilerOptions": {
"noEmit": true // Pick ONE strategy - this disables ALL output
}
}
Option 'declaration' cannot be used without 'emitDeclarationOnly' when 'noEmit' is set

What this error means

TypeScript's compiler options for file emission fall into distinct categories: - **noEmit**: Disables all output - no .js files, source maps, or declaration files - **emitDeclarationOnly**: Only emits .d.ts declaration files, no JavaScript - **declaration**: Emits both .js and .d.ts files When you have `"noEmit": true` in your configuration, TypeScript doesn't emit anything at all. If you also try to use `"declaration": true` (which requires some form of output), or `"emitDeclarationOnly": true` (which contradicts noEmit by emitting declarations), TypeScript throws error TS5053. This conflict typically arises when: 1. Your tsconfig.json extends a base configuration that sets noEmit 2. You're overriding those settings inconsistently 3. You have conflicting compiler options passed via CLI and config file

Typical symptoms

  • TypeScript compilation fails immediately with TS5053 error
  • The error appears after updating TypeScript or changing tsconfig.json
  • Building or type-checking works in some contexts but fails in others
  • You're using a monorepo where tsconfig files extend shared configs
  • The error prevents any build process from starting

Common causes

  1. Your tsconfig.json sets noEmit: true while also specifying declaration: true or emitDeclarationOnly: true
  2. You're extending a base tsconfig (like tsconfig.lib.json) that has conflicting options
  3. An extended config has noEmit set, and you're trying to override with emitDeclarationOnly
  4. You specified --noEmit on the CLI while your tsconfig has emitDeclarationOnly: true
  5. A tool (like tsc --noEmit) is overriding your configuration

How to fix "Option 'declaration' cannot be used without 'emitDeclarationOnly' when 'noEmit' is set"

1Identify your primary emit strategy

First, determine what you need:

- Type-checking only (CI/CD linting): Use "noEmit": true
- Generate declarations only (type-only packages): Use "emitDeclarationOnly": true
- Generate both .js and .d.ts (libraries/apps): Use "declaration": true (with noEmit: false or omitted)

Add this to your tsconfig.json based on your use case:

json
{
  "compilerOptions": {
    "noEmit": true  // Pick ONE strategy - this disables ALL output
  }
}

OR

json
{
  "compilerOptions": {
    "emitDeclarationOnly": true,  // Emit only .d.ts files
    "declaration": true
  }
}

OR

json
{
  "compilerOptions": {
    "declaration": true,  // Emit .d.ts alongside .js
    "noEmit": false       // Explicitly allow emission (or omit, default is false)
  }
}
2Remove conflicting options from tsconfig.json

Open your tsconfig.json and ensure you don't have both noEmit and emitDeclarationOnly:

WRONG:

json
{
  "compilerOptions": {
    "noEmit": true,
    "emitDeclarationOnly": true  // These conflict!
  }
}

WRONG:

json
{
  "compilerOptions": {
    "noEmit": true,
    "declaration": true  // This requires output!
  }
}

CORRECT (type-checking only):

json
{
  "compilerOptions": {
    "noEmit": true
  }
}

CORRECT (declarations only):

json
{
  "compilerOptions": {
    "emitDeclarationOnly": true,
    "declaration": true
  }
}
3Check for inherited configs in extends

If your tsconfig extends a base config, the conflict may come from there:

json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "emitDeclarationOnly": true  // Overrides noEmit from base
  }
}

Check what's in tsconfig.base.json:

bash
cat tsconfig.base.json | grep -A5 '"compilerOptions"'

If the base config has "noEmit": true, you must explicitly override:

json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "noEmit": false,  // Override inherited noEmit
    "emitDeclarationOnly": true,
    "declaration": true
  }
}
4For monorepo/workspace setups, use separate configs

In a monorepo with multiple packages, create separate TypeScript configs:

tsconfig.json (shared base, for type-checking):

json
{
  "compilerOptions": {
    "noEmit": true,
    "target": "ES2020",
    "module": "ESNext"
  }
}

tsconfig.build.json (for building libraries):

json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "noEmit": false,
    "declaration": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}

Then in your build script:

bash
# Type check (no output)
tsc --noEmit

# Build (emits .js and .d.ts)
tsc --project tsconfig.build.json
5Verify the fix by running tsc

Test your configuration:

bash
# Check for errors (no output files created)
npx tsc --noEmit

# Or build if using emitDeclarationOnly
npx tsc

If successful, you should see no TS5053 error. Check that:
- Type-checking passes
- If you have emitDeclarationOnly, .d.ts files are created
- If you have declaration: true, both .js and .d.ts files are created
- If you have noEmit: true, no output directory is created

Advanced notes

### Understanding the Three Options

noEmit: true
- Use case: CI/CD type-checking, linting, IDE checking
- Output: None (zero files written)
- Common in: GitHub Actions workflows, pre-commit hooks, test suites

emitDeclarationOnly: true
- Use case: Pure TypeScript libraries that need .d.ts files only
- Output: Only .d.ts files (no .js)
- Requires: Some other tool (Babel, swc, esbuild) to handle JavaScript transpilation
- Common in: Libraries with separate JS build process, monorepo packages

declaration: true (default noEmit: false)
- Use case: Applications and libraries with direct TypeScript output
- Output: Both .js and .d.ts files
- Common in: Traditional build setups, full-stack applications

### CLI Override Behavior

If you run tsc with CLI flags, they override tsconfig settings. Be careful with:

bash
# This conflicts if tsconfig has emitDeclarationOnly
npx tsc --noEmit

# This conflicts if tsconfig has noEmit
npx tsc --emitDeclarationOnly

To avoid surprises, specify the strategy in tsconfig.json and let scripts use it:

bash
npx tsc                    # Uses tsconfig.json settings
npx tsc --project tsconfig.build.json  # Uses alternate config

### Multi-package monorepos

Nx, Turborepo, and similar tools often set conflicting configs. If you get this error in a monorepo:

1. Check the root tsconfig.json and any extended configs
2. Ensure each package's tsconfig.json is explicit about its emit strategy
3. Use the tool's documentation (Nx: project.json, Turborepo: turbo.json) to override compiler options

Frequently asked questions

What does "TS5053" mean?
ts files When you have "noEmit": true in your configuration, TypeScript doesn't emit anything at all. If you also try to use "declaration": true (which requires some form of output), or "emitDeclarationOnly": true (which contradicts noEmit by emitting declarations), TypeScript throws error TS5053. This conflict typically arises when: 1.
How do I fix "TS5053"?
This error occurs when TypeScript compiler options conflict in your tsconfig.json file. The declaration option requires either emitDeclarationOnly or a normal emit mode, but noEmit prevents all file emission. The fix involves choosing one option strategy and removing conflicting settings.
What causes "TS5053"?
Your tsconfig.json sets noEmit: true while also specifying declaration: true or emitDeclarationOnly: true You're extending a base tsconfig (like tsconfig.lib.json) that has conflicting options An extended config has noEmit set, and you're trying to override with emitDeclarationOnly
Is the "TS5053" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading