Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3116,27 +3116,27 @@ namespace ts {
function resolveAlias(symbol: Symbol): Symbol {
Debug.assert((symbol.flags & SymbolFlags.Alias) !== 0, "Should only get Alias here.");
const links = getSymbolLinks(symbol);
if (!links.target) {
links.target = resolvingSymbol;
if (!links.aliasTarget) {
links.aliasTarget = resolvingSymbol;
const node = getDeclarationOfAliasSymbol(symbol);
if (!node) return Debug.fail();
const target = getTargetOfAliasDeclaration(node);
if (links.target === resolvingSymbol) {
links.target = target || unknownSymbol;
if (links.aliasTarget === resolvingSymbol) {
links.aliasTarget = target || unknownSymbol;
}
else {
error(node, Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
}
}
else if (links.target === resolvingSymbol) {
links.target = unknownSymbol;
else if (links.aliasTarget === resolvingSymbol) {
links.aliasTarget = unknownSymbol;
}
return links.target;
return links.aliasTarget;
}

function tryResolveAlias(symbol: Symbol): Symbol | undefined {
const links = getSymbolLinks(symbol);
if (links.target !== resolvingSymbol) {
if (links.aliasTarget !== resolvingSymbol) {
return resolveAlias(symbol);
}

Expand Down Expand Up @@ -31640,7 +31640,7 @@ namespace ts {
const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default);
newSymbol.parent = originalSymbol;
newSymbol.nameType = getStringLiteralType("default");
newSymbol.target = resolveSymbol(symbol);
newSymbol.aliasTarget = resolveSymbol(symbol);
memberTable.set(InternalSymbolName.Default, newSymbol);
return createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray);
}
Expand Down Expand Up @@ -42137,11 +42137,11 @@ namespace ts {
const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol;
return leftSpread ? [leftSpread, rightSpread!]
: syntheticOrigin ? [syntheticOrigin]
: singleElementArray(tryGetAliasTarget(symbol));
: singleElementArray(tryGetTarget(symbol));
}
return undefined;
}
function tryGetAliasTarget(symbol: Symbol): Symbol | undefined {
function tryGetTarget(symbol: Symbol): Symbol | undefined {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this function didn't need to be renamed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was renamed because it handles .target rather than .aliasTarget lookups, for clarity.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, my comment was misguided because of GitHub's silent truncation of the diff. It looked like this function was handling .aliasTarget still. All good.

let target: Symbol | undefined;
let next: Symbol | undefined = symbol;
while (next = getSymbolLinks(next).target) {
Expand Down Expand Up @@ -42393,7 +42393,7 @@ namespace ts {
if (links?.referenced) {
return true;
}
const target = getSymbolLinks(symbol!).target; // TODO: GH#18217
const target = getSymbolLinks(symbol!).aliasTarget; // TODO: GH#18217
if (target && getEffectiveModifierFlags(node) & ModifierFlags.Export &&
target.flags & SymbolFlags.Value &&
(shouldPreserveConstEnums(compilerOptions) || !isConstEnumOrConstEnumOnlyModule(target))) {
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4941,7 +4941,8 @@ namespace ts {
/* @internal */
export interface SymbolLinks {
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
target?: Symbol; // Resolved (non-alias) target of an alias
aliasTarget?: Symbol, // Resolved (non-alias) target of an alias
target?: Symbol; // Original version of an instantiated symbol
type?: Type; // Type of value symbol
writeType?: Type; // Type of value symbol in write contexts
nameType?: Type; // Type associated with a late-bound symbol
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//// [tests/cases/compiler/spreadExpressionContextualTypeWithNamespace.ts] ////

//// [spreadExpressionContextualTypeWithNamespace_0.ts]
// Repro from #44179 with some modification

function func() {}
class klass {}
const obj = { x: true };

export { func, klass, obj };

export function exportedDirectly() {}

//// [spreadExpressionContextualTypeWithNamespace_1.ts]
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";

stuff.func;
stuff.klass;
stuff.obj;
stuff.exportedDirectly;

function getStuff<T>() {
const thing = { ...stuff };
thing.func;
thing.klass;
thing.obj;
thing.exportedDirectly;
return thing;
}

getStuff().func;
getStuff().klass;
getStuff().obj;
getStuff().exportedDirectly;


//// [spreadExpressionContextualTypeWithNamespace_0.js]
"use strict";
// Repro from #44179 with some modification
exports.__esModule = true;
exports.exportedDirectly = exports.obj = exports.klass = exports.func = void 0;
function func() { }
exports.func = func;
var klass = /** @class */ (function () {
function klass() {
}
return klass;
}());
exports.klass = klass;
var obj = { x: true };
exports.obj = obj;
function exportedDirectly() { }
exports.exportedDirectly = exportedDirectly;
//// [spreadExpressionContextualTypeWithNamespace_1.js]
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
var stuff = require("./spreadExpressionContextualTypeWithNamespace_0");
stuff.func;
stuff.klass;
stuff.obj;
stuff.exportedDirectly;
function getStuff() {
var thing = __assign({}, stuff);
thing.func;
thing.klass;
thing.obj;
thing.exportedDirectly;
return thing;
}
getStuff().func;
getStuff().klass;
getStuff().obj;
getStuff().exportedDirectly;
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_0.ts ===
// Repro from #44179 with some modification

function func() {}
>func : Symbol(func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 0, 0))

class klass {}
>klass : Symbol(klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 2, 18))

const obj = { x: true };
>obj : Symbol(obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 4, 5))
>x : Symbol(x, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 4, 13))

export { func, klass, obj };
>func : Symbol(func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>klass : Symbol(klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>obj : Symbol(obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))

export function exportedDirectly() {}
>exportedDirectly : Symbol(exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))

=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_1.ts ===
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))

stuff.func;
>stuff.func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))

stuff.klass;
>stuff.klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))

stuff.obj;
>stuff.obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))

stuff.exportedDirectly;
>stuff.exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))

function getStuff<T>() {
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>T : Symbol(T, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 7, 18))

const thing = { ...stuff };
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>stuff : Symbol(stuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 0, 6))

thing.func;
>thing.func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))

thing.klass;
>thing.klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))

thing.obj;
>thing.obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))

thing.exportedDirectly;
>thing.exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))

return thing;
>thing : Symbol(thing, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 8, 7))
}

getStuff().func;
>getStuff().func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>func : Symbol(stuff.func, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 8))

getStuff().klass;
>getStuff().klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>klass : Symbol(stuff.klass, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 14))

getStuff().obj;
>getStuff().obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>obj : Symbol(stuff.obj, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 21))

getStuff().exportedDirectly;
>getStuff().exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))
>getStuff : Symbol(getStuff, Decl(spreadExpressionContextualTypeWithNamespace_1.ts, 5, 23))
>exportedDirectly : Symbol(stuff.exportedDirectly, Decl(spreadExpressionContextualTypeWithNamespace_0.ts, 6, 28))

Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_0.ts ===
// Repro from #44179 with some modification

function func() {}
>func : () => void

class klass {}
>klass : klass

const obj = { x: true };
>obj : { x: boolean; }
>{ x: true } : { x: boolean; }
>x : boolean
>true : true

export { func, klass, obj };
>func : () => void
>klass : typeof klass
>obj : { x: boolean; }

export function exportedDirectly() {}
>exportedDirectly : () => void

=== tests/cases/compiler/spreadExpressionContextualTypeWithNamespace_1.ts ===
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";
>stuff : typeof stuff

stuff.func;
>stuff.func : () => void
>stuff : typeof stuff
>func : () => void

stuff.klass;
>stuff.klass : typeof stuff.klass
>stuff : typeof stuff
>klass : typeof stuff.klass

stuff.obj;
>stuff.obj : { x: boolean; }
>stuff : typeof stuff
>obj : { x: boolean; }

stuff.exportedDirectly;
>stuff.exportedDirectly : () => void
>stuff : typeof stuff
>exportedDirectly : () => void

function getStuff<T>() {
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }

const thing = { ...stuff };
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>{ ...stuff } : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>stuff : typeof stuff

thing.func;
>thing.func : () => void
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>func : () => void

thing.klass;
>thing.klass : typeof stuff.klass
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>klass : typeof stuff.klass

thing.obj;
>thing.obj : { x: boolean; }
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>obj : { x: boolean; }

thing.exportedDirectly;
>thing.exportedDirectly : () => void
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>exportedDirectly : () => void

return thing;
>thing : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
}

getStuff().func;
>getStuff().func : () => void
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>func : () => void

getStuff().klass;
>getStuff().klass : typeof stuff.klass
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>klass : typeof stuff.klass

getStuff().obj;
>getStuff().obj : { x: boolean; }
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>obj : { x: boolean; }

getStuff().exportedDirectly;
>getStuff().exportedDirectly : () => void
>getStuff() : { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>getStuff : <T>() => { exportedDirectly(): void; func: () => void; klass: typeof stuff.klass; obj: { x: boolean; }; }
>exportedDirectly : () => void

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @filename: spreadExpressionContextualTypeWithNamespace_0.ts

// Repro from #44179 with some modification

function func() {}
class klass {}
const obj = { x: true };

export { func, klass, obj };

export function exportedDirectly() {}

// @filename: spreadExpressionContextualTypeWithNamespace_1.ts
import * as stuff from "./spreadExpressionContextualTypeWithNamespace_0";

stuff.func;
stuff.klass;
stuff.obj;
stuff.exportedDirectly;

function getStuff<T>() {
const thing = { ...stuff };
thing.func;
thing.klass;
thing.obj;
thing.exportedDirectly;
return thing;
}

getStuff().func;
getStuff().klass;
getStuff().obj;
getStuff().exportedDirectly;