Skip to content

Commit dab3691

Browse files
committed
Merge pull request #550 from Microsoft/deferredTypeLiterals
Deferred resolution of object literal members to support recursive types.
2 parents 2f7429e + be08411 commit dab3691

File tree

4 files changed

+38
-29
lines changed

4 files changed

+38
-29
lines changed

src/compiler/checker.ts

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,27 +1801,39 @@ module ts {
18011801

18021802
function resolveAnonymousTypeMembers(type: ObjectType) {
18031803
var symbol = type.symbol;
1804-
var members = emptySymbols;
1805-
var callSignatures = emptyArray;
1806-
var constructSignatures = emptyArray;
1807-
if (symbol.flags & SymbolFlags.HasExports) {
1808-
members = symbol.exports;
1809-
}
1810-
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
1811-
callSignatures = getSignaturesOfSymbol(symbol);
1804+
if (symbol.flags & SymbolFlags.TypeLiteral) {
1805+
var members = symbol.members;
1806+
var callSignatures = getSignaturesOfSymbol(members["__call"]);
1807+
var constructSignatures = getSignaturesOfSymbol(members["__new"]);
1808+
var stringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String);
1809+
var numberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number);
18121810
}
1813-
if (symbol.flags & SymbolFlags.Class) {
1814-
var classType = getDeclaredTypeOfClass(symbol);
1815-
constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
1816-
if (!constructSignatures.length) constructSignatures = getDefaultConstructSignatures(classType);
1817-
if (classType.baseTypes.length) {
1818-
var members = createSymbolTable(getNamedMembers(members));
1819-
addInheritedMembers(members, getPropertiesOfType(getTypeOfSymbol(classType.baseTypes[0].symbol)));
1811+
else {
1812+
// Combinations of function, class, enum and module
1813+
var members = emptySymbols;
1814+
var callSignatures: Signature[] = emptyArray;
1815+
var constructSignatures: Signature[] = emptyArray;
1816+
if (symbol.flags & SymbolFlags.HasExports) {
1817+
members = symbol.exports;
18201818
}
1819+
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) {
1820+
callSignatures = getSignaturesOfSymbol(symbol);
1821+
}
1822+
if (symbol.flags & SymbolFlags.Class) {
1823+
var classType = getDeclaredTypeOfClass(symbol);
1824+
constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
1825+
if (!constructSignatures.length) {
1826+
constructSignatures = getDefaultConstructSignatures(classType);
1827+
}
1828+
if (classType.baseTypes.length) {
1829+
members = createSymbolTable(getNamedMembers(members));
1830+
addInheritedMembers(members, getPropertiesOfType(getTypeOfSymbol(classType.baseTypes[0].symbol)));
1831+
}
1832+
}
1833+
var stringIndexType: Type = undefined;
1834+
var numberIndexType: Type = (symbol.flags & SymbolFlags.Enum) ? stringType : undefined;
18211835
}
1822-
var numberIndexType = (symbol.flags & SymbolFlags.Enum) ? stringType : undefined;
1823-
1824-
setObjectTypeMembers(type, members, callSignatures, constructSignatures, /* stringIndexType */ undefined, numberIndexType);
1836+
setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
18251837
}
18261838

18271839
function resolveObjectTypeMembers(type: ObjectType): ResolvedObjectType {
@@ -2276,13 +2288,8 @@ module ts {
22762288
function getTypeFromTypeLiteralNode(node: TypeLiteralNode): Type {
22772289
var links = getNodeLinks(node);
22782290
if (!links.resolvedType) {
2279-
var symbol = node.symbol;
2280-
var members = symbol.members;
2281-
var callSignatures = getSignaturesOfSymbol(members["__call"]);
2282-
var constructSignatures = getSignaturesOfSymbol(members["__new"]);
2283-
var stringIndexType = getIndexTypeOfSymbol(symbol, IndexKind.String);
2284-
var numberIndexType = getIndexTypeOfSymbol(symbol, IndexKind.Number);
2285-
links.resolvedType = createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
2291+
// Deferred resolution of members is handled by resolveObjectTypeMembers
2292+
links.resolvedType = createObjectType(TypeFlags.Anonymous, node.symbol);
22862293
}
22872294
return links.resolvedType;
22882295
}

tests/baselines/reference/declFileTypeofFunction.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ declare function f(n: typeof f): string;
6868
declare function f(n: typeof g): string;
6969
declare function g(n: typeof g): number;
7070
declare function g(n: typeof f): number;
71-
declare var b: any;
71+
declare var b: () => any;
7272
declare function b1(): typeof b1;
7373
declare function foo(): typeof foo;
7474
declare var foo1: typeof foo;

tests/baselines/reference/declFileTypeofFunction.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ function g() { return undefined; }
2929
>undefined : undefined
3030

3131
var b: () => typeof b;
32-
>b : any
33-
>b : any
32+
>b : () => any
33+
>b : () => any
3434

3535
function b1() {
3636
>b1 : () => typeof b1

tests/baselines/reference/recursiveFunctionTypes.errors.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
==== tests/cases/compiler/recursiveFunctionTypes.ts (12 errors) ====
1+
==== tests/cases/compiler/recursiveFunctionTypes.ts (13 errors) ====
22
function fn(): typeof fn { return 1; }
33
~
44
!!! Type 'number' is not assignable to type '() => typeof fn'.
@@ -39,6 +39,8 @@
3939

4040
var f4: () => typeof f4;
4141
f4 = 3; // error
42+
~~
43+
!!! Type 'number' is not assignable to type '() => any'.
4244

4345
function f5() { return f5; }
4446

0 commit comments

Comments
 (0)