Merge pull request #6091 from Microsoft/circularTypeofIssue
Fix circular typeof issue in function/namespace combo
This commit is contained in:
commit
ef9f4043c4
5 changed files with 128 additions and 25 deletions
|
@ -3608,37 +3608,29 @@ namespace ts {
|
|||
|
||||
function resolveAnonymousTypeMembers(type: AnonymousType) {
|
||||
const symbol = type.symbol;
|
||||
let members: SymbolTable;
|
||||
let callSignatures: Signature[];
|
||||
let constructSignatures: Signature[];
|
||||
let stringIndexType: Type;
|
||||
let numberIndexType: Type;
|
||||
|
||||
if (type.target) {
|
||||
members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
|
||||
callSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper, instantiateSignature);
|
||||
constructSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper, instantiateSignature);
|
||||
stringIndexType = instantiateType(getIndexTypeOfType(type.target, IndexKind.String), type.mapper);
|
||||
numberIndexType = instantiateType(getIndexTypeOfType(type.target, IndexKind.Number), type.mapper);
|
||||
const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
|
||||
const callSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper, instantiateSignature);
|
||||
const constructSignatures = instantiateList(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper, instantiateSignature);
|
||||
const stringIndexType = instantiateType(getIndexTypeOfType(type.target, IndexKind.String), type.mapper);
|
||||
const numberIndexType = instantiateType(getIndexTypeOfType(type.target, IndexKind.Number), type.mapper);
|
||||
setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
|
||||
}
|
||||
else if (symbol.flags & SymbolFlags.TypeLiteral) {
|
||||
members = symbol.members;
|
||||
callSignatures = getSignaturesOfSymbol(members["__call"]);
|
||||
constructSignatures = getSignaturesOfSymbol(members["__new"]);
|
||||
stringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String);
|
||||
numberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number);
|
||||
const members = symbol.members;
|
||||
const callSignatures = getSignaturesOfSymbol(members["__call"]);
|
||||
const constructSignatures = getSignaturesOfSymbol(members["__new"]);
|
||||
const stringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String);
|
||||
const numberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number);
|
||||
setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
|
||||
}
|
||||
else {
|
||||
// Combinations of function, class, enum and module
|
||||
members = emptySymbols;
|
||||
callSignatures = emptyArray;
|
||||
constructSignatures = emptyArray;
|
||||
let members = emptySymbols;
|
||||
let constructSignatures: Signature[] = emptyArray;
|
||||
if (symbol.flags & SymbolFlags.HasExports) {
|
||||
members = getExportsOfSymbol(symbol);
|
||||
}
|
||||
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
|
||||
callSignatures = getSignaturesOfSymbol(symbol);
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
const classType = getDeclaredTypeOfClassOrInterface(symbol);
|
||||
constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
|
||||
|
@ -3651,10 +3643,16 @@ namespace ts {
|
|||
addInheritedMembers(members, getPropertiesOfObjectType(baseConstructorType));
|
||||
}
|
||||
}
|
||||
stringIndexType = undefined;
|
||||
numberIndexType = (symbol.flags & SymbolFlags.Enum) ? stringType : undefined;
|
||||
const numberIndexType = (symbol.flags & SymbolFlags.Enum) ? stringType : undefined;
|
||||
setObjectTypeMembers(type, members, emptyArray, constructSignatures, undefined, numberIndexType);
|
||||
// We resolve the members before computing the signatures because a signature may use
|
||||
// typeof with a qualified name expression that circularly references the type we are
|
||||
// in the process of resolving (see issue #6072). The temporarily empty signature list
|
||||
// will never be observed because a qualified name can't reference signatures.
|
||||
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
|
||||
(<ResolvedType>type).callSignatures = getSignaturesOfSymbol(symbol);
|
||||
}
|
||||
}
|
||||
setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
|
||||
}
|
||||
|
||||
function resolveStructuredTypeMembers(type: ObjectType): ResolvedType {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
//// [circularTypeofWithFunctionModule.ts]
|
||||
// Repro from #6072
|
||||
|
||||
class Foo {}
|
||||
|
||||
function maker (value: string): typeof maker.Bar {
|
||||
return maker.Bar;
|
||||
}
|
||||
|
||||
namespace maker {
|
||||
export class Bar extends Foo {}
|
||||
}
|
||||
|
||||
|
||||
//// [circularTypeofWithFunctionModule.js]
|
||||
// Repro from #6072
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var Foo = (function () {
|
||||
function Foo() {
|
||||
}
|
||||
return Foo;
|
||||
}());
|
||||
function maker(value) {
|
||||
return maker.Bar;
|
||||
}
|
||||
var maker;
|
||||
(function (maker) {
|
||||
var Bar = (function (_super) {
|
||||
__extends(Bar, _super);
|
||||
function Bar() {
|
||||
_super.apply(this, arguments);
|
||||
}
|
||||
return Bar;
|
||||
}(Foo));
|
||||
maker.Bar = Bar;
|
||||
})(maker || (maker = {}));
|
|
@ -0,0 +1,27 @@
|
|||
=== tests/cases/compiler/circularTypeofWithFunctionModule.ts ===
|
||||
// Repro from #6072
|
||||
|
||||
class Foo {}
|
||||
>Foo : Symbol(Foo, Decl(circularTypeofWithFunctionModule.ts, 0, 0))
|
||||
|
||||
function maker (value: string): typeof maker.Bar {
|
||||
>maker : Symbol(maker, Decl(circularTypeofWithFunctionModule.ts, 2, 12), Decl(circularTypeofWithFunctionModule.ts, 6, 1))
|
||||
>value : Symbol(value, Decl(circularTypeofWithFunctionModule.ts, 4, 16))
|
||||
>maker.Bar : Symbol(maker.Bar, Decl(circularTypeofWithFunctionModule.ts, 8, 17))
|
||||
>maker : Symbol(maker, Decl(circularTypeofWithFunctionModule.ts, 2, 12), Decl(circularTypeofWithFunctionModule.ts, 6, 1))
|
||||
>Bar : Symbol(maker.Bar, Decl(circularTypeofWithFunctionModule.ts, 8, 17))
|
||||
|
||||
return maker.Bar;
|
||||
>maker.Bar : Symbol(maker.Bar, Decl(circularTypeofWithFunctionModule.ts, 8, 17))
|
||||
>maker : Symbol(maker, Decl(circularTypeofWithFunctionModule.ts, 2, 12), Decl(circularTypeofWithFunctionModule.ts, 6, 1))
|
||||
>Bar : Symbol(maker.Bar, Decl(circularTypeofWithFunctionModule.ts, 8, 17))
|
||||
}
|
||||
|
||||
namespace maker {
|
||||
>maker : Symbol(maker, Decl(circularTypeofWithFunctionModule.ts, 2, 12), Decl(circularTypeofWithFunctionModule.ts, 6, 1))
|
||||
|
||||
export class Bar extends Foo {}
|
||||
>Bar : Symbol(Bar, Decl(circularTypeofWithFunctionModule.ts, 8, 17))
|
||||
>Foo : Symbol(Foo, Decl(circularTypeofWithFunctionModule.ts, 0, 0))
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
=== tests/cases/compiler/circularTypeofWithFunctionModule.ts ===
|
||||
// Repro from #6072
|
||||
|
||||
class Foo {}
|
||||
>Foo : Foo
|
||||
|
||||
function maker (value: string): typeof maker.Bar {
|
||||
>maker : typeof maker
|
||||
>value : string
|
||||
>maker.Bar : typeof maker.Bar
|
||||
>maker : typeof maker
|
||||
>Bar : typeof maker.Bar
|
||||
|
||||
return maker.Bar;
|
||||
>maker.Bar : typeof maker.Bar
|
||||
>maker : typeof maker
|
||||
>Bar : typeof maker.Bar
|
||||
}
|
||||
|
||||
namespace maker {
|
||||
>maker : typeof maker
|
||||
|
||||
export class Bar extends Foo {}
|
||||
>Bar : Bar
|
||||
>Foo : Foo
|
||||
}
|
||||
|
11
tests/cases/compiler/circularTypeofWithFunctionModule.ts
Normal file
11
tests/cases/compiler/circularTypeofWithFunctionModule.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Repro from #6072
|
||||
|
||||
class Foo {}
|
||||
|
||||
function maker (value: string): typeof maker.Bar {
|
||||
return maker.Bar;
|
||||
}
|
||||
|
||||
namespace maker {
|
||||
export class Bar extends Foo {}
|
||||
}
|
Loading…
Reference in a new issue