diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 17c23660820..f3d6d4fcc47 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -3709,6 +3709,10 @@
"category": "Message",
"code": 90027
},
+ "Call decorator expression.": {
+ "category": "Message",
+ "code": 90028
+ },
"Convert function to an ES2015 class": {
"category": "Message",
diff --git a/src/services/codefixes/addMissingInvocationForDecorator.ts b/src/services/codefixes/addMissingInvocationForDecorator.ts
new file mode 100644
index 00000000000..7f17aab6db2
--- /dev/null
+++ b/src/services/codefixes/addMissingInvocationForDecorator.ts
@@ -0,0 +1,20 @@
+/* @internal */
+namespace ts.codefix {
+ registerCodeFix({
+ errorCodes: [Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code],
+ getCodeActions: (context: CodeFixContext) => {
+ const sourceFile = context.sourceFile;
+ const token = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
+ const decorator = getAncestor(token, SyntaxKind.Decorator) as Decorator;
+ Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
+ const replacement = createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
+ const changeTracker = textChanges.ChangeTracker.fromContext(context);
+ changeTracker.replaceNode(sourceFile, decorator.expression, replacement);
+
+ return [{
+ description: getLocaleSpecificMessage(Diagnostics.Call_decorator_expression),
+ changes: changeTracker.getChanges()
+ }];
+ }
+ });
+}
diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts
index 9bc80cad691..b024dfae7cd 100644
--- a/src/services/codefixes/fixes.ts
+++ b/src/services/codefixes/fixes.ts
@@ -1,3 +1,4 @@
+///
///
///
///