diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts
index 41845616bbe4b..d5c384e9161cc 100644
--- a/src/services/preProcess.ts
+++ b/src/services/preProcess.ts
@@ -345,6 +345,42 @@ namespace ts {
                     break;
                 }
 
+                if (scanner.getToken() === SyntaxKind.TemplateHead) {
+                    const stack = [scanner.getToken()];
+                    let token = scanner.scan();
+                    loop: while (length(stack)) {
+                        switch (token) {
+                            case SyntaxKind.EndOfFileToken:
+                                break loop;
+                            case SyntaxKind.ImportKeyword:
+                                tryConsumeImport();
+                                break;
+                            case SyntaxKind.TemplateHead:
+                                stack.push(token);
+                                break;
+                            case SyntaxKind.OpenBraceToken:
+                                if (length(stack)) {
+                                    stack.push(token);
+                                }
+                                break;
+                            case SyntaxKind.CloseBraceToken:
+                                if (length(stack)) {
+                                    if (lastOrUndefined(stack) === SyntaxKind.TemplateHead) {
+                                        if (scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === SyntaxKind.TemplateTail) {
+                                            stack.pop();
+                                        }
+                                    }
+                                    else {
+                                        stack.pop();
+                                    }
+                                }
+                                break;
+                        }
+                        token = scanner.scan();
+                    }
+                    nextToken();
+                }
+
                 // check if at least one of alternative have moved scanner forward
                 if (tryConsumeDeclare() ||
                     tryConsumeImport() ||
diff --git a/src/testRunner/unittests/services/preProcessFile.ts b/src/testRunner/unittests/services/preProcessFile.ts
index fb7a7e62649d4..a6369d6e4d4cf 100644
--- a/src/testRunner/unittests/services/preProcessFile.ts
+++ b/src/testRunner/unittests/services/preProcessFile.ts
@@ -176,6 +176,177 @@ describe("unittests:: services:: PreProcessFile:", () => {
             });
         });
 
+        it("Correctly ignore commented imports following template expression", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("/**" + "\n" +
+                " * Before" + "\n" +
+                " * ```" + "\n" +
+                " * import * as a from \"a\";" + "\n" +
+                " * ```" + "\n" +
+                " */" + "\n" +
+                "type Foo = `${string}`;" + "\n" +
+                "/**" + "\n" +
+                " * After" + "\n" +
+                " * ```" + "\n" +
+                " * import { B } from \"b\";" + "\n" +
+                " * import * as c from \"c\";" + "\n" +
+                " * ```" + "\n" +
+                " */",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns imports after a template expression", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("`${foo}`; import \"./foo\";",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [
+                    { fileName: "./foo", pos: 17, end: 22 }
+                ],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns dynamic imports from template expression", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("`${(
Text `` ${} text {} " + "\n" +
+                "${import(\"a\")} {import(\"b\")} " + "\n" +
+                "${/* A comment */} ${/* import(\"ignored\") */} 
)}`",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [
+                    { fileName: "a", pos: 39, end: 40 },
+                    { fileName: "b", pos: 53, end: 54 }
+                ],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns dynamic imports from nested template expression", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("`${foo(`${bar(`${import(\"a\")} ${import(\"b\")}`, `${baz(`${import(\"c\") ${import(\"d\")}`)}`)}`)}`",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [
+                    { fileName: "a", pos: 24, end: 25 },
+                    { fileName: "b", pos: 39, end: 40 },
+                    { fileName: "c", pos: 64, end: 65 },
+                    { fileName: "d", pos: 78, end: 79 },
+                ],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns dynamic imports from tagged template expression", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("foo`${ fn({ a: 100 }, import(\"a\"), `${import(\"b\")}`, import(\"c\"), `${import(\"d\")} foo`, import(\"e\")) }`",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [
+                    { fileName: "a", pos: 29, end: 30 },
+                    { fileName: "b", pos: 45, end: 46 },
+                    { fileName: "c", pos: 60, end: 61 },
+                    { fileName: "d", pos: 76, end: 77 },
+                    { fileName: "e", pos: 95, end: 96 },
+                ],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns dynamic imports from template expression and imports following it", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("const x = `hello ${await import(\"a\").default}`;" + "\n\n" +
+                "import { y } from \"b\";",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [
+                    { fileName: "a", pos: 32, end: 33 },
+                    { fileName: "b", pos: 67, end: 68 },
+                ],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns dynamic imports from template expressions and other imports", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("const x = `x ${await import(\"a\").default}`;" + "\n\n" +
+                "import { y } from \"b\";" + "\n" +
+                "const y = `y ${import(\"c\")}`;" + "\n\n" +
+                "import { d } from \"d\";",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [
+                    { fileName: "a", pos: 28, end: 29 },
+                    { fileName: "b", pos: 63, end: 64 },
+                    { fileName: "c", pos: 90, end: 91 },
+                    { fileName: "d", pos: 117, end: 118 },
+                ],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
+        it("Correctly returns empty importedFiles with incorrect template expression", () => {
+            /* eslint-disable no-template-curly-in-string */
+            test("const foo = `${",
+            /*readImportFile*/ true,
+            /*detectJavaScriptImports*/ true,
+            {
+                referencedFiles: [],
+                typeReferenceDirectives: [],
+                libReferenceDirectives: [],
+                importedFiles: [],
+                ambientExternalModules: undefined,
+                isLibFile: false
+            });
+            /* eslint-enable no-template-curly-in-string */
+        });
+
         it("Correctly return ES6 exports", () => {
             test("export * from \"m1\";" + "\n" +
                 "export {a} from \"m2\";" + "\n" +