mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
feat(part of 40169): add spelling suggestion/quick fix for module/namespace exported members (#40211)
This commit is contained in:
@@ -2678,7 +2678,7 @@ namespace ts {
|
||||
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
|
||||
if (suggestion !== undefined) {
|
||||
const suggestionName = symbolToString(suggestion);
|
||||
const diagnostic = error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
|
||||
const diagnostic = error(name, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
|
||||
if (suggestion.valueDeclaration) {
|
||||
addRelatedInfo(diagnostic,
|
||||
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
|
||||
@@ -3057,7 +3057,12 @@ namespace ts {
|
||||
symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning));
|
||||
if (!symbol) {
|
||||
if (!ignoreErrors) {
|
||||
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), declarationNameToString(right));
|
||||
const namespaceName = getFullyQualifiedName(namespace);
|
||||
const declarationName = declarationNameToString(right);
|
||||
const suggestion = getSuggestedSymbolForNonexistentModule(right, namespace);
|
||||
suggestion ?
|
||||
error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestion)) :
|
||||
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -2752,7 +2752,7 @@
|
||||
"category": "Error",
|
||||
"code": 2723
|
||||
},
|
||||
"Module '{0}' has no exported member '{1}'. Did you mean '{2}'?": {
|
||||
"'{0}' has no exported member named '{1}'. Did you mean '{2}'?": {
|
||||
"category": "Error",
|
||||
"code": 2724
|
||||
},
|
||||
@@ -3029,7 +3029,6 @@
|
||||
"code": 2792
|
||||
},
|
||||
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace ts.codefix {
|
||||
Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
|
||||
Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
|
||||
Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
|
||||
Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2.code,
|
||||
Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2.code,
|
||||
// for JSX class components
|
||||
Diagnostics.No_overload_matches_this_call.code,
|
||||
// for JSX FC
|
||||
@@ -53,6 +53,12 @@ namespace ts.codefix {
|
||||
}
|
||||
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, containingType);
|
||||
}
|
||||
else if (isQualifiedName(parent) && parent.right === node) {
|
||||
const symbol = checker.getSymbolAtLocation(parent.left);
|
||||
if (symbol && symbol.flags & SymbolFlags.Module) {
|
||||
suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(parent.right, symbol);
|
||||
}
|
||||
}
|
||||
else if (isImportSpecifier(parent) && parent.name === node) {
|
||||
Debug.assertNode(node, isIdentifier, "Expected an identifier for spelling (import)");
|
||||
const importDeclaration = findAncestor(node, isImportDeclaration)!;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: Module '"./a"' has no exported member 'assertNevar'. Did you mean 'assertNever'?
|
||||
tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: '"./a"' has no exported member named 'assertNevar'. Did you mean 'assertNever'?
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/modules/a.ts (0 errors) ====
|
||||
@@ -9,6 +9,6 @@ tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: Module '"./a"' has
|
||||
==== tests/cases/conformance/es6/modules/b.ts (1 errors) ====
|
||||
import { assertNevar } from "./a";
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2724: Module '"./a"' has no exported member 'assertNevar'. Did you mean 'assertNever'?
|
||||
!!! error TS2724: '"./a"' has no exported member named 'assertNevar'. Did you mean 'assertNever'?
|
||||
!!! related TS2728 tests/cases/conformance/es6/modules/a.ts:1:17: 'assertNever' is declared here.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
C:/foo/bar/Baz/src/sample.ts(1,10): error TS2724: Module '"./utils.js"' has no exported member 'exit'. Did you mean 'exist'?
|
||||
C:/foo/bar/Baz/src/sample.ts(1,10): error TS2724: '"./utils.js"' has no exported member named 'exit'. Did you mean 'exist'?
|
||||
|
||||
|
||||
==== C:/foo/bar/Baz/src/utils.ts (0 errors) ====
|
||||
@@ -6,7 +6,7 @@ C:/foo/bar/Baz/src/sample.ts(1,10): error TS2724: Module '"./utils.js"' has no e
|
||||
==== C:/foo/bar/Baz/src/sample.ts (1 errors) ====
|
||||
import { exit } from "./utils.js";
|
||||
~~~~
|
||||
!!! error TS2724: Module '"./utils.js"' has no exported member 'exit'. Did you mean 'exist'?
|
||||
!!! error TS2724: '"./utils.js"' has no exported member named 'exit'. Did you mean 'exist'?
|
||||
!!! related TS2728 C:/foo/bar/Baz/src/utils.ts:1:17: 'exist' is declared here.
|
||||
|
||||
exit()
|
||||
@@ -1,6 +1,6 @@
|
||||
tests/cases/compiler/moduleVisibilityTest3.ts(20,22): error TS2709: Cannot use namespace 'modes' as a type.
|
||||
tests/cases/compiler/moduleVisibilityTest3.ts(20,39): error TS2694: Namespace '_modes' has no exported member 'Mode'.
|
||||
tests/cases/compiler/moduleVisibilityTest3.ts(21,22): error TS2694: Namespace '_modes' has no exported member 'Mode'.
|
||||
tests/cases/compiler/moduleVisibilityTest3.ts(20,39): error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
|
||||
tests/cases/compiler/moduleVisibilityTest3.ts(21,22): error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
|
||||
|
||||
|
||||
==== tests/cases/compiler/moduleVisibilityTest3.ts (3 errors) ====
|
||||
@@ -27,10 +27,10 @@ tests/cases/compiler/moduleVisibilityTest3.ts(21,22): error TS2694: Namespace '_
|
||||
~~~~~
|
||||
!!! error TS2709: Cannot use namespace 'modes' as a type.
|
||||
~~~~
|
||||
!!! error TS2694: Namespace '_modes' has no exported member 'Mode'.
|
||||
!!! error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
|
||||
var x:modes.Mode;
|
||||
~~~~
|
||||
!!! error TS2694: Namespace '_modes' has no exported member 'Mode'.
|
||||
!!! error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
31
tests/baselines/reference/moduleVisibilityTest4.errors.txt
Normal file
31
tests/baselines/reference/moduleVisibilityTest4.errors.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
tests/cases/compiler/moduleVisibilityTest4.ts(9,11): error TS2724: 'M' has no exported member named 'num'. Did you mean 'nums'?
|
||||
tests/cases/compiler/moduleVisibilityTest4.ts(11,11): error TS2694: Namespace 'M' has no exported member 'bar'.
|
||||
tests/cases/compiler/moduleVisibilityTest4.ts(13,11): error TS2724: 'N' has no exported member named 'num'. Did you mean 'nums'?
|
||||
tests/cases/compiler/moduleVisibilityTest4.ts(15,11): error TS2694: Namespace 'N' has no exported member 'bar'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/moduleVisibilityTest4.ts (4 errors) ====
|
||||
module M {
|
||||
export type nums = number;
|
||||
}
|
||||
|
||||
namespace N {
|
||||
export type nums = number;
|
||||
}
|
||||
|
||||
let a1: M.num;
|
||||
~~~
|
||||
!!! error TS2724: 'M' has no exported member named 'num'. Did you mean 'nums'?
|
||||
let b1: M.nums;
|
||||
let c1: M.bar;
|
||||
~~~
|
||||
!!! error TS2694: Namespace 'M' has no exported member 'bar'.
|
||||
|
||||
let a2: N.num;
|
||||
~~~
|
||||
!!! error TS2724: 'N' has no exported member named 'num'. Did you mean 'nums'?
|
||||
let b2: N.nums;
|
||||
let c2: N.bar;
|
||||
~~~
|
||||
!!! error TS2694: Namespace 'N' has no exported member 'bar'.
|
||||
|
||||
25
tests/baselines/reference/moduleVisibilityTest4.js
Normal file
25
tests/baselines/reference/moduleVisibilityTest4.js
Normal file
@@ -0,0 +1,25 @@
|
||||
//// [moduleVisibilityTest4.ts]
|
||||
module M {
|
||||
export type nums = number;
|
||||
}
|
||||
|
||||
namespace N {
|
||||
export type nums = number;
|
||||
}
|
||||
|
||||
let a1: M.num;
|
||||
let b1: M.nums;
|
||||
let c1: M.bar;
|
||||
|
||||
let a2: N.num;
|
||||
let b2: N.nums;
|
||||
let c2: N.bar;
|
||||
|
||||
|
||||
//// [moduleVisibilityTest4.js]
|
||||
var a1;
|
||||
var b1;
|
||||
var c1;
|
||||
var a2;
|
||||
var b2;
|
||||
var c2;
|
||||
41
tests/baselines/reference/moduleVisibilityTest4.symbols
Normal file
41
tests/baselines/reference/moduleVisibilityTest4.symbols
Normal file
@@ -0,0 +1,41 @@
|
||||
=== tests/cases/compiler/moduleVisibilityTest4.ts ===
|
||||
module M {
|
||||
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
|
||||
|
||||
export type nums = number;
|
||||
>nums : Symbol(nums, Decl(moduleVisibilityTest4.ts, 0, 10))
|
||||
}
|
||||
|
||||
namespace N {
|
||||
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
|
||||
|
||||
export type nums = number;
|
||||
>nums : Symbol(nums, Decl(moduleVisibilityTest4.ts, 4, 13))
|
||||
}
|
||||
|
||||
let a1: M.num;
|
||||
>a1 : Symbol(a1, Decl(moduleVisibilityTest4.ts, 8, 3))
|
||||
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
|
||||
|
||||
let b1: M.nums;
|
||||
>b1 : Symbol(b1, Decl(moduleVisibilityTest4.ts, 9, 3))
|
||||
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
|
||||
>nums : Symbol(M.nums, Decl(moduleVisibilityTest4.ts, 0, 10))
|
||||
|
||||
let c1: M.bar;
|
||||
>c1 : Symbol(c1, Decl(moduleVisibilityTest4.ts, 10, 3))
|
||||
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
|
||||
|
||||
let a2: N.num;
|
||||
>a2 : Symbol(a2, Decl(moduleVisibilityTest4.ts, 12, 3))
|
||||
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
|
||||
|
||||
let b2: N.nums;
|
||||
>b2 : Symbol(b2, Decl(moduleVisibilityTest4.ts, 13, 3))
|
||||
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
|
||||
>nums : Symbol(N.nums, Decl(moduleVisibilityTest4.ts, 4, 13))
|
||||
|
||||
let c2: N.bar;
|
||||
>c2 : Symbol(c2, Decl(moduleVisibilityTest4.ts, 14, 3))
|
||||
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
|
||||
|
||||
35
tests/baselines/reference/moduleVisibilityTest4.types
Normal file
35
tests/baselines/reference/moduleVisibilityTest4.types
Normal file
@@ -0,0 +1,35 @@
|
||||
=== tests/cases/compiler/moduleVisibilityTest4.ts ===
|
||||
module M {
|
||||
export type nums = number;
|
||||
>nums : number
|
||||
}
|
||||
|
||||
namespace N {
|
||||
export type nums = number;
|
||||
>nums : number
|
||||
}
|
||||
|
||||
let a1: M.num;
|
||||
>a1 : any
|
||||
>M : any
|
||||
|
||||
let b1: M.nums;
|
||||
>b1 : number
|
||||
>M : any
|
||||
|
||||
let c1: M.bar;
|
||||
>c1 : any
|
||||
>M : any
|
||||
|
||||
let a2: N.num;
|
||||
>a2 : any
|
||||
>N : any
|
||||
|
||||
let b2: N.nums;
|
||||
>b2 : number
|
||||
>N : any
|
||||
|
||||
let c2: N.bar;
|
||||
>c2 : any
|
||||
>N : any
|
||||
|
||||
@@ -34,7 +34,7 @@ Output::
|
||||
[[90m12:00:31 AM[0m] Starting compilation in watch mode...
|
||||
|
||||
|
||||
[96ma/b/project/src/main2.ts[0m:[93m1[0m:[93m114[0m - [91merror[0m[90m TS2694: [0mNamespace 'Common.SomeComponent.DynamicMenu' has no exported member 'z'.
|
||||
[96ma/b/project/src/main2.ts[0m:[93m1[0m:[93m114[0m - [91merror[0m[90m TS2724: [0m'Common.SomeComponent.DynamicMenu' has no exported member named 'z'. Did you mean 'Z'?
|
||||
|
||||
[7m1[0m namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }
|
||||
[7m [0m [91m ~[0m
|
||||
|
||||
@@ -34,7 +34,7 @@ Output::
|
||||
[[90m12:00:31 AM[0m] Starting compilation in watch mode...
|
||||
|
||||
|
||||
[96ma/b/project/src/main2.ts[0m:[93m1[0m:[93m114[0m - [91merror[0m[90m TS2694: [0mNamespace 'Common.SomeComponent.DynamicMenu' has no exported member 'z'.
|
||||
[96ma/b/project/src/main2.ts[0m:[93m1[0m:[93m114[0m - [91merror[0m[90m TS2724: [0m'Common.SomeComponent.DynamicMenu' has no exported member named 'z'. Did you mean 'Z'?
|
||||
|
||||
[7m1[0m namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }
|
||||
[7m [0m [91m ~[0m
|
||||
|
||||
15
tests/cases/compiler/moduleVisibilityTest4.ts
Normal file
15
tests/cases/compiler/moduleVisibilityTest4.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
module M {
|
||||
export type nums = number;
|
||||
}
|
||||
|
||||
namespace N {
|
||||
export type nums = number;
|
||||
}
|
||||
|
||||
let a1: M.num;
|
||||
let b1: M.nums;
|
||||
let c1: M.bar;
|
||||
|
||||
let a2: N.num;
|
||||
let b2: N.nums;
|
||||
let c2: N.bar;
|
||||
12
tests/cases/fourslash/codeFixSpelling7.ts
Normal file
12
tests/cases/fourslash/codeFixSpelling7.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////namespace Foo {
|
||||
//// export type nums = number;
|
||||
////}
|
||||
////let x: Foo.[|num|];
|
||||
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Change_spelling_to_0.message, "nums"],
|
||||
newRangeContent: "nums"
|
||||
});
|
||||
12
tests/cases/fourslash/codeFixSpelling8.ts
Normal file
12
tests/cases/fourslash/codeFixSpelling8.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////module Foo {
|
||||
//// export type nums = number;
|
||||
////}
|
||||
////let x: Foo.[|num|];
|
||||
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Change_spelling_to_0.message, "nums"],
|
||||
newRangeContent: "nums"
|
||||
});
|
||||
15
tests/cases/fourslash/codeFixSpelling9.ts
Normal file
15
tests/cases/fourslash/codeFixSpelling9.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @filename: a.ts
|
||||
////module Foo {
|
||||
//// export type nums = number;
|
||||
////}
|
||||
// @filename: b.ts
|
||||
////let x: Foo.[|num|];
|
||||
|
||||
goTo.file("b.ts");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: [ts.Diagnostics.Change_spelling_to_0.message, "nums"],
|
||||
newRangeContent: "nums"
|
||||
});
|
||||
Reference in New Issue
Block a user