From 4cd20b1335b551abfcc4c2d74c3d40e1c1730c3b Mon Sep 17 00:00:00 2001 From: Noel Varanda Date: Fri, 19 May 2017 17:38:04 +0100 Subject: [PATCH] Fix #15540: Throw error when importing @types (#15866) * Fix #15540: Throw error when importing @types Fix issue: #15540 - Modify checker; external imports to account for imported modules containing '@types/'. - Add diagnostic message. - Add test case * FIX-15540: Review changes - Replace `substr` with `startsWith` - move diagnostics message to more relevant place - Add `removePrefix` helper function --- src/compiler/checker.ts | 6 ++++++ src/compiler/core.ts | 5 +++++ src/compiler/diagnosticMessages.json | 4 ++++ .../reference/importDeclTypes.errors.txt | 14 ++++++++++++++ tests/baselines/reference/importDeclTypes.js | 15 +++++++++++++++ tests/cases/compiler/importDeclTypes.ts | 9 +++++++++ 6 files changed, 53 insertions(+) create mode 100644 tests/baselines/reference/importDeclTypes.errors.txt create mode 100644 tests/baselines/reference/importDeclTypes.js create mode 100644 tests/cases/compiler/importDeclTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 799cde7cdb3..9ce987c3f58 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1642,6 +1642,12 @@ namespace ts { return; } + if (startsWith(moduleReference, "@types/")) { + const diag = Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1; + const withoutAtTypePrefix = removePrefix(moduleReference, "@types/"); + error(errorNode, diag, withoutAtTypePrefix, moduleReference); + } + const ambientModule = tryFindAmbientModule(moduleName, /*withAugmentations*/ true); if (ambientModule) { return ambientModule; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 60553fdab01..4cb55f0fe30 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1764,6 +1764,11 @@ namespace ts { return str.lastIndexOf(prefix, 0) === 0; } + /* @internal */ + export function removePrefix(str: string, prefix: string): string { + return startsWith(str, prefix) ? str.substr(prefix.length) : str; + } + /* @internal */ export function endsWith(str: string, suffix: string): boolean { const expectedPos = str.length - suffix.length; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ffedb45c2e0..d4fc40399ed 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3061,6 +3061,10 @@ "category": "Message", "code": 6136 }, + "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'.": { + "category": "Error", + "code": 6137 + }, "Property '{0}' is declared but never used.": { "category": "Error", "code": 6138 diff --git a/tests/baselines/reference/importDeclTypes.errors.txt b/tests/baselines/reference/importDeclTypes.errors.txt new file mode 100644 index 00000000000..dfb8fcb6f48 --- /dev/null +++ b/tests/baselines/reference/importDeclTypes.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/a.ts(1,21): error TS6137: Cannot import type declaration files. Consider importing 'foo-bar' instead of '@types/foo-bar'. + + +==== /node_modules/@types/foo-bar/index.d.ts (0 errors) ==== + export interface Foo { + bar: string; + } + + // This should error +==== tests/cases/compiler/a.ts (1 errors) ==== + import { Foo } from "@types/foo-bar"; + ~~~~~~~~~~~~~~~~ +!!! error TS6137: Cannot import type declaration files. Consider importing 'foo-bar' instead of '@types/foo-bar'. + \ No newline at end of file diff --git a/tests/baselines/reference/importDeclTypes.js b/tests/baselines/reference/importDeclTypes.js new file mode 100644 index 00000000000..640dd4a19b4 --- /dev/null +++ b/tests/baselines/reference/importDeclTypes.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/importDeclTypes.ts] //// + +//// [index.d.ts] +export interface Foo { + bar: string; +} + +// This should error +//// [a.ts] +import { Foo } from "@types/foo-bar"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/cases/compiler/importDeclTypes.ts b/tests/cases/compiler/importDeclTypes.ts new file mode 100644 index 00000000000..01fcd0e7b6f --- /dev/null +++ b/tests/cases/compiler/importDeclTypes.ts @@ -0,0 +1,9 @@ + +// @filename: /node_modules/@types/foo-bar/index.d.ts +export interface Foo { + bar: string; +} + +// This should error +// @filename: a.ts +import { Foo } from "@types/foo-bar";