Fix missing error for accessing type-only export * member through namespace (#57176)

This commit is contained in:
Andrew Branch 2024-01-30 17:04:13 -08:00 committed by GitHub
parent d21b1d271f
commit d2d3b24737
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 223 additions and 0 deletions

View File

@ -14914,6 +14914,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (type.flags & TypeFlags.Object) {
const resolved = resolveStructuredTypeMembers(type as ObjectType);
const symbol = resolved.members.get(name);
if (symbol && !includeTypeOnlyMembers && type.symbol?.flags & SymbolFlags.ValueModule && getSymbolLinks(type.symbol).typeOnlyExportStarMap?.has(name)) {
// If this is the type of a module, `resolved.members.get(name)` might have effectively skipped over
// an `export type * from './foo'`, leaving `symbolIsValue` unable to see that the symbol is being
// viewed through a type-only export.
return undefined;
}
if (symbol && symbolIsValue(symbol, includeTypeOnlyMembers)) {
return symbol;
}

View File

@ -0,0 +1,14 @@
main.ts(2,52): error TS2339: Property 'Ghost' does not exist on type 'typeof import("intermediate")'.
==== main.ts (1 errors) ====
import * as intermediate from './intermediate'
const ghost: intermediate.Ghost = new intermediate.Ghost()
~~~~~
!!! error TS2339: Property 'Ghost' does not exist on type 'typeof import("intermediate")'.
==== intermediate.ts (0 errors) ====
export type * from './ghost'
==== ghost.ts (0 errors) ====
export class Ghost {}

View File

@ -0,0 +1,30 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace11.ts] ////
//// [main.ts]
import * as intermediate from './intermediate'
const ghost: intermediate.Ghost = new intermediate.Ghost()
//// [intermediate.ts]
export type * from './ghost'
//// [ghost.ts]
export class Ghost {}
//// [ghost.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ghost = void 0;
var Ghost = /** @class */ (function () {
function Ghost() {
}
return Ghost;
}());
exports.Ghost = Ghost;
//// [intermediate.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var intermediate = require("./intermediate");
var ghost = new intermediate.Ghost();

View File

@ -0,0 +1,20 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace11.ts] ////
=== main.ts ===
import * as intermediate from './intermediate'
>intermediate : Symbol(intermediate, Decl(main.ts, 0, 6))
const ghost: intermediate.Ghost = new intermediate.Ghost()
>ghost : Symbol(ghost, Decl(main.ts, 1, 5))
>intermediate : Symbol(intermediate, Decl(main.ts, 0, 6))
>Ghost : Symbol(intermediate.Ghost, Decl(ghost.ts, 0, 0))
>intermediate : Symbol(intermediate, Decl(main.ts, 0, 6))
=== intermediate.ts ===
export type * from './ghost'
=== ghost.ts ===
export class Ghost {}
>Ghost : Symbol(Ghost, Decl(ghost.ts, 0, 0))

View File

@ -0,0 +1,22 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace11.ts] ////
=== main.ts ===
import * as intermediate from './intermediate'
>intermediate : typeof intermediate
const ghost: intermediate.Ghost = new intermediate.Ghost()
>ghost : intermediate.Ghost
>intermediate : any
>new intermediate.Ghost() : any
>intermediate.Ghost : any
>intermediate : typeof intermediate
>Ghost : any
=== intermediate.ts ===
export type * from './ghost'
=== ghost.ts ===
export class Ghost {}
>Ghost : Ghost

View File

@ -0,0 +1,20 @@
main.ts(3,13): error TS1362: 'c' cannot be used as a value because it was exported using 'export type'.
main.ts(4,19): error TS2339: Property 'c' does not exist on type 'typeof import("types")'.
==== main.ts (2 errors) ====
import { c } from './types'
import * as types from './types'
console.log(c) // Fails as expected, import is still allowed though.
~
!!! error TS1362: 'c' cannot be used as a value because it was exported using 'export type'.
!!! related TS1377 types.ts:1:1: 'c' was exported here.
console.log(types.c) // Expected an error here.
~
!!! error TS2339: Property 'c' does not exist on type 'typeof import("types")'.
==== types.ts (0 errors) ====
export type * from './values'
==== values.ts (0 errors) ====
export const c = 10

View File

@ -0,0 +1,28 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace12.ts] ////
//// [main.ts]
import { c } from './types'
import * as types from './types'
console.log(c) // Fails as expected, import is still allowed though.
console.log(types.c) // Expected an error here.
//// [types.ts]
export type * from './values'
//// [values.ts]
export const c = 10
//// [values.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.c = void 0;
exports.c = 10;
//// [types.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [main.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var types = require("./types");
console.log(c); // Fails as expected, import is still allowed though.
console.log(types.c); // Expected an error here.

View File

@ -0,0 +1,29 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace12.ts] ////
=== main.ts ===
import { c } from './types'
>c : Symbol(c, Decl(main.ts, 0, 8))
import * as types from './types'
>types : Symbol(types, Decl(main.ts, 1, 6))
console.log(c) // Fails as expected, import is still allowed though.
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>c : Symbol(c, Decl(main.ts, 0, 8))
console.log(types.c) // Expected an error here.
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>types : Symbol(types, Decl(main.ts, 1, 6))
=== types.ts ===
export type * from './values'
=== values.ts ===
export const c = 10
>c : Symbol(c, Decl(values.ts, 0, 12))

View File

@ -0,0 +1,34 @@
//// [tests/cases/conformance/externalModules/typeOnly/exportNamespace12.ts] ////
=== main.ts ===
import { c } from './types'
>c : 10
import * as types from './types'
>types : typeof types
console.log(c) // Fails as expected, import is still allowed though.
>console.log(c) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>c : 10
console.log(types.c) // Expected an error here.
>console.log(types.c) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>types.c : any
>types : typeof types
>c : any
=== types.ts ===
export type * from './values'
=== values.ts ===
export const c = 10
>c : 10
>10 : 10

View File

@ -0,0 +1,9 @@
// @filename: main.ts
import * as intermediate from './intermediate'
const ghost: intermediate.Ghost = new intermediate.Ghost()
// @filename: intermediate.ts
export type * from './ghost'
// @filename: ghost.ts
export class Ghost {}

View File

@ -0,0 +1,11 @@
// @filename: main.ts
import { c } from './types'
import * as types from './types'
console.log(c) // Fails as expected, import is still allowed though.
console.log(types.c) // Expected an error here.
// @filename: types.ts
export type * from './values'
// @filename: values.ts
export const c = 10