Question
Understanding the Experimental Decorators Warning in TypeScript
Question
I am getting this TypeScript warning:
Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.
However, my tsconfig.json already includes:
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
What is confusing is that some classes using decorators in the same project do not show the warning, while many others do.
What can cause this inconsistent behavior in the TypeScript compiler?
Short Answer
By the end of this page, you will understand what the experimentalDecorators warning means in TypeScript, why it can still appear even when the option is enabled, and how to troubleshoot configuration, tooling, and project-structure issues that cause inconsistent behavior.
Concept
Decorators in TypeScript are a language feature that must be explicitly enabled. The experimentalDecorators compiler option tells TypeScript that your project intentionally uses decorators.
If that option is enabled and you still see the warning, the most important idea is this:
- the file may not actually be compiled with the
tsconfig.jsonyou think it is - a different tool may be compiling the file
- the editor may be using a different TypeScript project context
- some files may belong to another
tsconfig.jsonor no project at all
In real projects, TypeScript code is often handled by more than one system:
- the TypeScript compiler (
tsc) - your editor's TypeScript language service
- a bundler such as Webpack, Vite, or esbuild
- a test runner
- Babel or another transpiler
That means one part of your setup may respect experimentalDecorators, while another part may ignore it or use a different config.
This matters because many TypeScript problems are not caused by syntax errors. They are caused by configuration scope: which files are included, which config is active, and which tool is reading it.
Mental Model
Think of tsconfig.json like a rulebook for a classroom.
You assume every student is following the same rulebook, but in reality:
- some students are in a different classroom
- some are using last week's rulebook
- some are being taught by a substitute teacher
Decorators warnings often happen for the same reason. You enabled the rule in one tsconfig.json, but some files are being checked under a different rulebook.
So the question is usually not "Did I set experimentalDecorators?" but "Which config is this file actually using?"
Syntax and Examples
The relevant TypeScript configuration looks like this:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
A simple decorator example:
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class UserService {
getUser() {
return "Alice";
}
}
What these options do
experimentalDecorators: true- Allows decorator syntax like
@sealed
- Allows decorator syntax like
Step by Step Execution
Consider this project structure:
project/
tsconfig.json
src/
app.ts
scripts/
generate.ts
And this tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true
},
"include": ["src/**/*"]
}
Now imagine these files:
// src/app.ts
function logClass(target: Function) {}
@logClass
class App {}
// scripts/generate.ts
function logClass(target: Function) {}
@logClass
{}
Real World Use Cases
Decorators are commonly used in frameworks and libraries that attach metadata or modify behavior.
Common examples
- Angular
@Component,@Injectable,@Directive
- NestJS
@Controller,@Get,@Injectable
- TypeORM
@Entity,@Column,@PrimaryGeneratedColumn
- Custom app infrastructure
- logging decorators
- validation decorators
- permission decorators
- caching decorators
Why the warning matters in practice
If one part of your app compiles with decorators enabled and another does not:
- builds may fail only in certain environments
- editors may show warnings that CI does not
- test files may behave differently from app files
- generated metadata may be missing in one part of the system
This is especially common in monorepos, apps with multiple tsconfig files, and projects using both Babel and TypeScript.
Real Codebase Usage
In real codebases, developers usually solve this by making configuration explicit and shared.
Common patterns
1. Base config inheritance
Create a shared base config:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Then extend it:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"outDir": "dist"
},
"include": ["src/**/*"]
}
This avoids one config accidentally missing decorator support.
2. Separate app and test configs
Common Mistakes
1. Assuming emitDecoratorMetadata enables decorators
Broken assumption:
{
"compilerOptions": {
"emitDecoratorMetadata": true
}
}
Why it fails:
emitDecoratorMetadataonly adds metadata- it does not allow
@decoratorsyntax
Fix:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
2. File is outside the include pattern
Broken config:
Comparisons
| Situation | What it means | Typical result |
|---|---|---|
experimentalDecorators: true | Decorator syntax is allowed | @MyDecorator compiles |
emitDecoratorMetadata: true only | Metadata emission requested, but decorators not enabled | Warning or compile error for decorators |
File included in active tsconfig.json | File uses project compiler options | Consistent behavior |
File not included in active tsconfig.json | File may be in inferred project | Warning may appear unexpectedly |
Terminal tsc works, editor warns | Editor is using different project/config/version | Inconsistent diagnostics |
| One extends another |
Cheat Sheet
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Quick rules
experimentalDecoratorsenables decorator syntaxemitDecoratorMetadatadoes not enable decorators by itself- a file must belong to the correct TypeScript project to get those settings
- multiple
tsconfigfiles can cause inconsistent behavior - editor warnings may differ from terminal builds
Useful checks
tsc --showConfig
tsc -p tsconfig.json
Things to inspect
- Is the file inside
include? - Is the file excluded?
- Is there another
tsconfigcloser to that file? - Does the project use
extends?
FAQ
Why do I get the decorators warning even though experimentalDecorators is true?
Usually because the file is not being compiled with the tsconfig.json you edited, or your editor is using a different TypeScript project context.
Why do only some files show the warning in the same project?
Those files may belong to a different tsconfig, be outside the include pattern, or be treated as inferred standalone files by the editor.
Does emitDecoratorMetadata enable decorators in TypeScript?
No. It only emits additional metadata. You still need experimentalDecorators: true.
How can I check which TypeScript config is being used?
Use tsc --showConfig for the active project config, and check your editor's TypeScript project information if available.
Can the problem come from my editor rather than the compiler?
Yes. Editors often run their own TypeScript language service, which can use a different TypeScript version or detect a different project.
Can multiple tsconfig.json files cause this issue?
Yes. This is one of the most common reasons for inconsistent decorator warnings.
Should I restart the TypeScript server after changing tsconfig.json?
Yes. Some editors cache project state, so restarting the TypeScript service can clear stale warnings.
Mini Project
Description
Build a small TypeScript project with two folders to demonstrate why one decorated file can work while another shows warnings. This helps you understand that compiler options only apply to files that belong to the active TypeScript project.
Goal
Create a project where src files support decorators, then fix configuration so scripts files support them too.
Requirements
- Create a
tsconfig.jsonthat enablesexperimentalDecorators. - Include only the
srcfolder at first. - Add one decorated class in
srcand one inscripts. - Update the config so both folders use the same decorator settings.
- Verify the final setup compiles consistently.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular Dependency Injection: Fix "Can't Resolve All Parameters for Component" Errors
Learn why Angular shows "Can't resolve all parameters for component" and how to fix service injection issues in components.