@@ -1789,7 +1789,7 @@ module ts {
1789
1789
function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags) {
1790
1790
let targetSymbol = getTargetSymbol(symbol);
1791
1791
if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface) {
1792
- buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterface (symbol), writer, enclosingDeclaraiton, flags);
1792
+ buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias (symbol), writer, enclosingDeclaraiton, flags);
1793
1793
}
1794
1794
}
1795
1795
@@ -2573,8 +2573,9 @@ module ts {
2573
2573
return appendOuterTypeParameters(undefined, getDeclarationOfKind(symbol, kind));
2574
2574
}
2575
2575
2576
- // The local type parameters are the combined set of type parameters from all declarations of the class or interface.
2577
- function getLocalTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] {
2576
+ // The local type parameters are the combined set of typ
10000
e parameters from all declarations of the class,
2577
+ // interface, or type alias.
2578
+ function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): TypeParameter[] {
2578
2579
let result: TypeParameter[];
2579
2580
for (let node of symbol.declarations) {
2580
2581
if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) {
@@ -2590,16 +2591,7 @@ module ts {
2590
2591
// The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
2591
2592
// its locally declared type parameters.
2592
2593
function getTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] {
2593
- return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterface(symbol));
2594
- }
2595
-
2596
- function getTypeParametersOfTypeAlias(symbol: Symbol): TypeParameter[] {
2597
- let links = getSymbolLinks(symbol);
2598
- if (!links.typeParameters) {
2599
- let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
2600
- links.typeParameters = declaration.typeParameters ? appendTypeParameters(undefined, declaration.typeParameters) : emptyArray;
2601
- }
2602
- return links.typeParameters;
2594
+ return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
2603
2595
}
2604
2596
2605
2597
function getBaseTypes(type: InterfaceType): ObjectType[] {
@@ -2672,7 +2664,7 @@ module ts {
2672
2664
let kind = symbol.flags & SymbolFlags.Class ? TypeFlags.Class : TypeFlags.Interface;
2673
2665
let type = links.declaredType = <InterfaceType>createObjectType(kind, symbol);
2674
2666
let outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol);
2675
- let localTypeParameters = getLocalTypeParametersOfClassOrInterface (symbol);
2667
+ let localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias (symbol);
2676
2668
if (outerTypeParameters || localTypeParameters) {
2677
2669
type.flags |= TypeFlags.Reference;
2678
2670
type.typeParameters = concatenate(outerTypeParameters, localTypeParameters);
@@ -2697,7 +2689,16 @@ module ts {
2697
2689
}
2698
2690
let declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
2699
2691
let type = getTypeFromTypeNode(declaration.type);
2700
- if (!popTypeResolution()) {
2692
+ if (popTypeResolution()) {
2693
+ links.typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
2694
+ if (links.typeParameters) {
2695
+ // Initialize the instantiation cache for generic type aliases. The declared type corresponds to
2696
+ // an instantiation of the type alias with the type parameters supplied as type arguments.
2697
+ links.instantiations = {};
2698
+ links.instantiations[getTypeListId(links.typeParameters)] = type;
2699
+ }
2700
+ }
2701
+ else {
2701
2702
type = unknownType;
2702
2703
error(declaration.name, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
2703
2704
}
@@ -3522,6 +3523,7 @@ module ts {
3522
3523
}
3523
3524
}
3524
3525
3526
+ // Get type from reference to class or interface
3525
3527
function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
3526
3528
let type = getDeclaredTypeOfSymbol(symbol);
3527
3529
let typeParameters = (<InterfaceType>type).localTypeParameters;
@@ -3543,22 +3545,20 @@ module ts {
3543
3545
return type;
3544
3546
}
3545
3547
3548
+ // Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
3549
+ // references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
3550
+ // declared type. Instantiations are cached using the type identities of the type arguments as the key.
3546
3551
function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
3547
3552
let type = getDeclaredTypeOfSymbol(symbol);
3548
- let typeParameters = getTypeParametersOfTypeAlias(symbol);
3549
- if (typeParameters.length) {
3553
+ let links = getSymbolLinks(symbol);
3554
+ let typeParameters = links.typeParameters;
3555
+ if (typeParameters) {
3550
3556
if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) {
3551
3557
error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length);
3552
3558
return unknownType;
3553
3559
}
3554
3560
let typeArguments = map(node.typeArguments, getTypeFromTypeNode);
3555
3561
let id = getTypeListId(typeArguments);
3556
- let links = getSymbolLinks(symbol);
3557
- if (!links.instantiations) {
3558
- links.instantiations = {};
3559
- // The declared type corresponds to an instantiation with its own type parameters as type arguments
3560
- links.instantiations[getTypeListId(typeParameters)] = type;
3561
- }
3562
3562
return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments)));
3563
3563
}
3564
3564
if (node.typeArguments) {
@@ -3568,12 +3568,20 @@ module ts {
3568
3568
return type;
3569
3569
}
3570
3570
3571
- function getTypeFromTypeParameterReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
3572
- // TypeScript 1.0 spec (April 2014): 3.4.1
3573
- // Type parameters declared in a particular type parameter list
3574
- // may not be referenced in constraints in that type parameter list
3575
- // Implementation: such type references are resolved to 'unknown' type that usually denotes error
3576
- return isTypeParameterReferenceIllegalInConstraint(node, symbol) ? unknownType : getDeclaredTypeOfSymbol(symbol);
3571
+ // Get type from reference to named type that cannot be generic (enum or type parameter)
3572
+ function getTypeFromNonGenericTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type {
3573
+ if (symbol.flags & SymbolFlags.TypeParameter && isTypeParameterReferenceIllegalInConstraint(node, symbol)) {
3574
+ // TypeScript 1.0 spec (April 2014): 3.4.1
3575
+ // Type parameters declared in a particular type parameter list
3576
+ // may not be referenced in constraints in that type parameter list
3577
+ // Implementation: such type references are resolved to 'unknown' type that usually denotes error
3578
+ return unknownType;
3579
+ }
3580
+ if (node.typeArguments) {
3581
+ error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
3582
+ return unknownType;
3583
+ }
3584
+ return getDeclaredTypeOfSymbol(symbol);
3577
3585
}
3578
3586
3579
3587
function getTypeFromTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments): Type {
@@ -3583,10 +3591,10 @@ module ts {
3583
3591
isSupportedExpressionWithTypeArguments(<ExpressionWithTypeArguments>node) ? (<ExpressionWithTypeArguments>node).expression :
3584
3592
undefined;
3585
3593
let symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
3586
- let type = symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) :
3587
- symbol.flags & SymbolFlags.TypeParameter ? getTypeFromTypeParameterReference (node, symbol) :
3594
+ let type = symbol === unknownSymbol ? unknownType :
3595
+ symbol.flags & ( SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference (node, symbol) :
3588
3596
symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) :
3589
- getDeclaredTypeOfSymbol( symbol);
3597
+ getTypeFromNonGenericTypeReference(node, symbol);
3590
3598
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
3591
3599
// type reference in checkTypeReferenceOrExpressionWithTypeArguments.
3592
3600
links.resolvedSymbol = symbol;
@@ -8786,7 +8794,7 @@ module ts {
8786
8794
if (type !== unknownType && node.typeArguments) {
8787
8795
// Do type argument local checks only if referenced type is successfully resolved
8788
8796
let symbol = getNodeLinks(node).resolvedSymbol;
8789
- let typeParameters = symbol.flags & SymbolFlags.TypeAlias ? getTypeParametersOfTypeAlias (symbol) : (<TypeReference>type).target.localTypeParameters;
8797
+ let typeParameters = symbol.flags & SymbolFlags.TypeAlias ? getSymbolLinks (symbol).typeParameters : (<TypeReference>type).target.localTypeParameters;
8790
8798
let len = node.typeArguments.length;
8791
8799
for (let i = 0; i < len; i++) {
8792
8800
checkSourceElement(node.typeArguments[i]);
0 commit comments