private void AnalyzeTypeReference([CanBeNull] ITypeNode type) { if (type == null || type.IsPredefinedType()) { return; } // Checking for named types like: // let n: CustomInterface = undefined; // ~~~~~~~~~~~~~~~ var typeReferenceNode = type.As <ITypeReferenceNode>(); if (typeReferenceNode != null) { EntityName entityName = typeReferenceNode.TypeName; AnalyzeTypeReference(entityName); AnalyzeTypeArguments(typeReferenceNode.TypeArguments); } // Checking for typed literals like: // let n: {x: number, y: number} = {x: 1, y: 3}; // ~~~~~~~~~~~~~~~~~~~~~~ var typeLiteralNode = type.As <ITypeLiteralNode>(); if (typeLiteralNode != null) { // Don't need to register names, because it is not a real interface declaration. AnalyzeInterfaceMembers(typeLiteralNode.Members, registerPropertyNames: false); } // Check for array types like: // let n: number[] = [1,2]; // ~~~~~~~~ var arrayTypeNode = type.As <IArrayTypeNode>(); if (arrayTypeNode != null) { AnalyzeTypeReference(arrayTypeNode.ElementType); } // Check for function types like: // function foo(): () => number {} // ~~~~~~~~~~~~ var functionType = type.As <IFunctionOrConstructorTypeNode>(); if (functionType != null) { AnalyzeParameters(functionType.Parameters); AnalyzeTypeReference(functionType.Type); AnalyzeTypeParameters(functionType.TypeParameters); } // Check for parenthesized types like: // function foo(): (() => number)[] {return [];} // ~~~~~~~~~~~~~~~~ var parenthesizedType = type.As <IParenthesizedTypeNode>(); if (parenthesizedType != null) { AnalyzeTypeReference(parenthesizedType.Type); } // Checking for union types like: // type X = string | number; // ~~~~~~~~~~~~~~~ var unionType = type.As <IUnionTypeNode>(); if (unionType != null) { foreach (var t in unionType.Types) { AnalyzeTypeReference(t); } } // Checking for tuple types like: // type X = [1, 2]; // ~~~~~~~~~~~~~~~ var tupleType = type.As <ITupleTypeNode>(); if (tupleType != null) { foreach (var t in tupleType.ElementTypes) { AnalyzeTypeReference(t); } } // Checking for type query like: // type X = typeof anIdentifier; // ~~~~~~~~~~~~~~~ var typeQueryType = type.As <ITypeQueryNode>(); if (typeQueryType != null) { var entityName = typeQueryType.ExprName; AnalyzeTypeReference(entityName); } }