Skip to content

Commit 3de032f

Browse files
authored
Allow usage of local value symbol merged with type-only import (microsoft#47642)
1 parent 9028051 commit 3de032f

File tree

5 files changed

+73
-18
lines changed

5 files changed

+73
-18
lines changed

Diff for: src/compiler/checker.ts

+12-18
Original file line numberDiff line numberDiff line change
@@ -2235,29 +2235,23 @@ namespace ts {
22352235
error(errorLocation, Diagnostics.Parameter_0_cannot_reference_identifier_1_declared_after_it, declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name), declarationNameToString(errorLocation as Identifier));
22362236
}
22372237
}
2238-
if (result && errorLocation && meaning & SymbolFlags.Value && result.flags & SymbolFlags.Alias) {
2239-
checkSymbolUsageInExpressionContext(result, name, errorLocation);
2238+
if (result && errorLocation && meaning & SymbolFlags.Value && result.flags & SymbolFlags.Alias && !(result.flags & SymbolFlags.Value) && !isValidTypeOnlyAliasUseSite(errorLocation)) {
2239+
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(result);
2240+
if (typeOnlyDeclaration) {
2241+
const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
2242+
? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type
2243+
: Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type;
2244+
const unescapedName = unescapeLeadingUnderscores(name);
2245+
addTypeOnlyDeclarationRelatedInfo(
2246+
error(errorLocation, message, unescapedName),
2247+
typeOnlyDeclaration,
2248+
unescapedName);
2249+
}
22402250
}
22412251
}
22422252
return result;
22432253
}
22442254

2245-
function checkSymbolUsageInExpressionContext(symbol: Symbol, name: __String, useSite: Node) {
2246-
if (!isValidTypeOnlyAliasUseSite(useSite)) {
2247-
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(symbol);
2248-
if (typeOnlyDeclaration) {
2249-
const message = typeOnlyDeclaration.kind === SyntaxKind.ExportSpecifier
2250-
? Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type
2251-
: Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type;
2252-
const unescapedName = unescapeLeadingUnderscores(name);
2253-
addTypeOnlyDeclarationRelatedInfo(
2254-
error(useSite, message, unescapedName),
2255-
typeOnlyDeclaration,
2256-
unescapedName);
2257-
}
2258-
}
2259-
}
2260-
22612255
function addTypeOnlyDeclarationRelatedInfo(diagnostic: Diagnostic, typeOnlyDeclaration: TypeOnlyCompatibleAliasDeclaration | undefined, unescapedName: string) {
22622256
if (!typeOnlyDeclaration) return diagnostic;
22632257
return addRelatedInfo(

Diff for: tests/baselines/reference/mergedWithLocalValue.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [tests/cases/conformance/externalModules/typeOnly/mergedWithLocalValue.ts] ////
2+
3+
//// [a.ts]
4+
export type A = "a";
5+
6+
//// [b.ts]
7+
import type { A } from "./a";
8+
const A: A = "a";
9+
A.toUpperCase();
10+
11+
12+
//// [a.js]
13+
"use strict";
14+
exports.__esModule = true;
15+
//// [b.js]
16+
"use strict";
17+
exports.__esModule = true;
18+
var A = "a";
19+
A.toUpperCase();
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
2+
export type A = "a";
3+
>A : Symbol(A, Decl(a.ts, 0, 0))
4+
5+
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
6+
import type { A } from "./a";
7+
>A : Symbol(A, Decl(b.ts, 0, 13), Decl(b.ts, 1, 5))
8+
9+
const A: A = "a";
10+
>A : Symbol(A, Decl(b.ts, 0, 13), Decl(b.ts, 1, 5))
11+
>A : Symbol(A, Decl(b.ts, 0, 13), Decl(b.ts, 1, 5))
12+
13+
A.toUpperCase();
14+
>A.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
15+
>A : Symbol(A, Decl(b.ts, 0, 13), Decl(b.ts, 1, 5))
16+
>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --))
17+

Diff for: tests/baselines/reference/mergedWithLocalValue.types

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
2+
export type A = "a";
3+
>A : "a"
4+
5+
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
6+
import type { A } from "./a";
7+
>A : "a"
8+
9+
const A: A = "a";
10+
>A : "a"
11+
>"a" : "a"
12+
13+
A.toUpperCase();
14+
>A.toUpperCase() : string
15+
>A.toUpperCase : () => string
16+
>A : "a"
17+
>toUpperCase : () => string
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @Filename: a.ts
2+
export type A = "a";
3+
4+
// @Filename: b.ts
5+
import type { A } from "./a";
6+
const A: A = "a";
7+
A.toUpperCase();

0 commit comments

Comments
 (0)