function getTypeForVariableLikeDeclaration(declaration) {
            // A variable declared in a for..in statement is always of type any
            if (declaration.parent.parent.kind === 200 /* ForInStatement */) {
                return anyType;
            }
            if (declaration.parent.parent.kind === 201 /* ForOfStatement */) {
                // checkRightHandSideOfForOf will return undefined if the for-of expression type was
                // missing properties/signatures required to get its iteratedType (like
                // [Symbol.iterator] or next). This may be because we accessed properties from anyType,
                // or it may have led to an error inside getElementTypeOfIterable.
                return checkRightHandSideOfForOf(declaration.parent.parent.expression) || anyType;
            }
            if (ts.isBindingPattern(declaration.parent)) {
                return getTypeForBindingElement(declaration);
            }
            // Use type from type annotation if one is present
            if (declaration.type) {
                return getTypeFromTypeNode(declaration.type);
            }
            if (declaration.kind === 138 /* Parameter */) {
                var func = declaration.parent;
                // For a parameter of a set accessor, use the type of the get accessor if one is present
                if (func.kind === 146 /* SetAccessor */ && !ts.hasDynamicName(func)) {
                    var getter = ts.getDeclarationOfKind(declaration.parent.symbol, 145 /* GetAccessor */);
                    if (getter) {
                        return getReturnTypeOfSignature(getSignatureFromDeclaration(getter));
                    }
                }
                // Use contextual parameter type if one is available
                var type = getContextuallyTypedParameterType(declaration);
                if (type) {
                    return type;
                }
            }
            // Use the type of the initializer expression if one is present
            if (declaration.initializer) {
                return checkExpressionCached(declaration.initializer);
            }
            // If it is a short-hand property assignment, use the type of the identifier
            if (declaration.kind === 246 /* ShorthandPropertyAssignment */) {
                return checkIdentifier(declaration.name);
            }
            // If the declaration specifies a binding pattern, use the type implied by the binding pattern
            if (ts.isBindingPattern(declaration.name)) {
                return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false);
            }
            // No type specified and nothing can be inferred
            return undefined;
        }

function getTypeForVariableLikeDeclaration ( declaration ) { if ( declaration . parent . parent . kind === 200 ) { return anyType ; } if ( declaration . parent . parent . kind === 201 ) { return checkRightHandSideOfForOf ( declaration . parent . parent . expression ) || anyType ; } if ( ts . isBindingPattern ( declaration . parent ) ) { return getTypeForBindingElement ( declaration ) ; } if ( declaration . type ) { return getTypeFromTypeNode ( declaration . type ) ; } if ( declaration . kind === 138 ) { var func = declaration . parent ; if ( func . kind === 146 && ! ts . hasDynamicName ( func ) ) { var getter = ts . getDeclarationOfKind ( declaration . parent . symbol , 145 ) ; if ( getter ) { return getReturnTypeOfSignature ( getSignatureFromDeclaration ( getter ) ) ; } } var type = getContextuallyTypedParameterType ( declaration ) ; if ( type ) { return type ; } } if ( declaration . initializer ) { return checkExpressionCached ( declaration . initializer ) ; } if ( declaration . kind === 246 ) { return checkIdentifier ( declaration . name ) ; } if ( ts . isBindingPattern ( declaration . name ) ) { return getTypeFromBindingPattern ( declaration . name , false ) ; } return undefined ; }

Return the inferred type for a variable, parameter, or property declaration

Return the inferred type for a variable parameter or property declaration


function getTypeFromBindingElement(element, includePatternInType) {
            if (element.initializer) {
                return getWidenedType(checkExpressionCached(element.initializer));
            }
            if (ts.isBindingPattern(element.name)) {
                return getTypeFromBindingPattern(element.name, includePatternInType);
            }
            return anyType;
        }

function getTypeFromBindingElement ( element , includePatternInType ) { if ( element . initializer ) { return getWidenedType ( checkExpressionCached ( element . initializer ) ) ; } if ( ts . isBindingPattern ( element . name ) ) { return getTypeFromBindingPattern ( element . name , includePatternInType ) ; } return anyType ; }

Return the type implied by a binding pattern element. This is the type of the initializer of the element if one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding pattern. Otherwise, it is the type any.

Return the type implied by a binding pattern element . This is the type of the initializer of the element if one is present . Otherwise if the element is itself a binding pattern it is the type implied by the binding pattern . Otherwise it is the type any .


function getTypeFromObjectBindingPattern(pattern, includePatternInType) {
            var members = {};
            ts.forEach(pattern.elements, function (e) {
                var flags = 4 /* Property */ | 67108864 /* Transient */ | (e.initializer ? 536870912 /* Optional */ : 0);
                var name = e.propertyName || e.name;
                var symbol = createSymbol(flags, name.text);
                symbol.type = getTypeFromBindingElement(e, includePatternInType);
                symbol.bindingElement = e;
                members[symbol.name] = symbol;
            });
            var result = createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined);
            if (includePatternInType) {
                result.pattern = pattern;
            }
            return result;
        }

function getTypeFromObjectBindingPattern ( pattern , includePatternInType ) { var members = { } ; ts . forEach ( pattern . elements , function ( e ) { var flags = 4 | 67108864 | ( e . initializer ? 536870912 : 0 ) ; var name = e . propertyName || e . name ; var symbol = createSymbol ( flags , name . text ) ; symbol . type = getTypeFromBindingElement ( e , includePatternInType ) ; symbol . bindingElement = e ; members [ symbol . name ] = symbol ; } ) ; var result = createAnonymousType ( undefined , members , emptyArray , emptyArray , undefined , undefined ) ; if ( includePatternInType ) { result . pattern = pattern ; } return result ; }

Return the type implied by an object binding pattern


function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) {
            var result;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var node = _a[_i];
                if (node.kind === 215 /* InterfaceDeclaration */ || node.kind === 214 /* ClassDeclaration */ ||
                    node.kind === 186 /* ClassExpression */ || node.kind === 216 /* TypeAliasDeclaration */) {
                    var declaration = node;
                    if (declaration.typeParameters) {
                        result = appendTypeParameters(result, declaration.typeParameters);
                    }
                }
            }
            return result;
        }

The local type parameters are the combined set of type parameters from all declarations of the class, interface, or type alias.

The local type parameters are the combined set of type parameters from all declarations of the class interface or type alias .


function getBaseConstructorTypeOfClass(type) {
            if (!type.resolvedBaseConstructorType) {
                var baseTypeNode = getBaseTypeNodeOfClass(type);
                if (!baseTypeNode) {
                    return type.resolvedBaseConstructorType = undefinedType;
                }
                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
                    return unknownType;
                }
                var baseConstructorType = checkExpression(baseTypeNode.expression);
                if (baseConstructorType.flags & 80896 /* ObjectType */) {
                    // Resolving the members of a class requires us to resolve the base class of that class.
                    // We force resolution here such that we catch circularities now.
                    resolveStructuredTypeMembers(baseConstructorType);
                }
                if (!popTypeResolution()) {
                    error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
                    return type.resolvedBaseConstructorType = unknownType;
                }
                if (baseConstructorType !== unknownType && baseConstructorType !== nullType && !isConstructorType(baseConstructorType)) {
                    error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
                    return type.resolvedBaseConstructorType = unknownType;
                }
                type.resolvedBaseConstructorType = baseConstructorType;
            }
            return type.resolvedBaseConstructorType;
        }

The base constructor of a class can resolve to undefinedType if the class has no extends clause, unknownType if an error occurred during resolution of the extends expression, nullType if the extends expression is the null value, or an object type with at least one construct signature.

The base constructor of a class can resolve to undefinedType if the class has no extends clause unknownType if an error occurred during resolution of the extends expression nullType if the extends expression is the null value or an object type with at least one construct signature .


function isIndependentTypeReference(node) {
            if (node.typeArguments) {
                for (var _i = 0, _a = node.typeArguments; _i < _a.length; _i++) {
                    var typeNode = _a[_i];
                    if (!isIndependentType(typeNode)) {
                        return false;
                    }
                }
            }
            return true;
        }

function isIndependentTypeReference ( node ) { if ( node . typeArguments ) { for ( var _i = 0 , _a = node . typeArguments ; _i < _a . length ; _i ++ ) { var typeNode = _a [ _i ] ; if ( ! isIndependentType ( typeNode ) ) { return false ; } } } return true ; }

A type reference is considered independent if each type argument is considered independent.

A type reference is considered independent if each type argument is considered independent .


function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) {
            var result = {};
            for (var _i = 0; _i < symbols.length; _i++) {
                var symbol = symbols[_i];
                result[symbol.name] = mappingThisOnly && isIndependentMember(symbol) ? symbol : instantiateSymbol(symbol, mapper);
            }
            return result;
        }

function createInstantiatedSymbolTable ( symbols , mapper , mappingThisOnly ) { var result = { } ; for ( var _i = 0 ; _i < symbols . length ; _i ++ ) { var symbol = symbols [ _i ] ; result [ symbol . name ] = mappingThisOnly && isIndependentMember ( symbol ) ? symbol : instantiateSymbol ( symbol , mapper ) ; } return result ; }

The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true, we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.

The mappingThisOnly flag indicates that the only type parameter being mapped is this . When the flag is true we check symbols to see if we can quickly conclude they are free of this references thus needing no instantiation .


function getUnionSignatures(types, kind) {
            var signatureLists = ts.map(types, function (t) { return getSignaturesOfType(t, kind); });
            var result = undefined;
            for (var i = 0; i < signatureLists.length; i++) {
                for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    // Only process signatures with parameter lists that aren't already in the result list
                    if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true)) {
                        var unionSignatures = findMatchingSignatures(signatureLists, signature, i);
                        if (unionSignatures) {
                            var s = signature;
                            // Union the result types when more than one signature matches
                            if (unionSignatures.length > 1) {
                                s = cloneSignature(signature);
                                // Clear resolved return type we possibly got from cloneSignature
                                s.resolvedReturnType = undefined;
                                s.unionSignatures = unionSignatures;
                            }
                            (result || (result = [])).push(s);
                        }
                    }
                }
            }
            return result || emptyArray;
        }

function getUnionSignatures ( types , kind ) { var signatureLists = ts . map ( types , function ( t ) { return getSignaturesOfType ( t , kind ) ; } ) ; var result = undefined ; for ( var i = 0 ; i < signatureLists . length ; i ++ ) { for ( var _i = 0 , _a = signatureLists [ i ] ; _i < _a . length ; _i ++ ) { var signature = _a [ _i ] ; if ( ! result || ! findMatchingSignature ( result , signature , false , true ) ) { var unionSignatures = findMatchingSignatures ( signatureLists , signature , i ) ; if ( unionSignatures ) { var s = signature ; if ( unionSignatures . length > 1 ) { s = cloneSignature ( signature ) ; s . resolvedReturnType = undefined ; s . unionSignatures = unionSignatures ; } ( result || ( result = [ ] ) ) . push ( s ) ; } } } } return result || emptyArray ; }

The signatures of a union type are those signatures that are present in each of the constituent types. Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional parameters and may differ in return types. When signatures differ in return types, the resulting return type is the union of the constituent return types.

The signatures of a union type are those signatures that are present in each of the constituent types . Generic signatures must match exactly but non - generic signatures are allowed to have extra optional parameters and may differ in return types . When signatures differ in return types the resulting return type is the union of the constituent return types .


function getPropertyOfObjectType(type, name) {
            if (type.flags & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (ts.hasProperty(resolved.members, name)) {
                    var symbol = resolved.members[name];
                    if (symbolIsValue(symbol)) {
                        return symbol;
                    }
                }
            }
        }

function getPropertyOfObjectType ( type , name ) { if ( type . flags & 80896 ) { var resolved = resolveStructuredTypeMembers ( type ) ; if ( ts . hasProperty ( resolved . members , name ) ) { var symbol = resolved . members [ name ] ; if ( symbolIsValue ( symbol ) ) { return symbol ; } } } }

If the given type is an object type and that type has a property by the given name, return the symbol for that property.Otherwise return undefined.

If the given type is an object type and that type has a property by the given name return the symbol for that property . Otherwise return undefined .


function getApparentType(type) {
            if (type.flags & 512 /* TypeParameter */) {
                do {
                    type = getConstraintOfTypeParameter(type);
                } while (type && type.flags & 512 /* TypeParameter */);
                if (!type) {
                    type = emptyObjectType;
                }
            }
            if (type.flags & 258 /* StringLike */) {
                type = globalStringType;
            }
            else if (type.flags & 132 /* NumberLike */) {
                type = globalNumberType;
            }
            else if (type.flags & 8 /* Boolean */) {
                type = globalBooleanType;
            }
            else if (type.flags & 16777216 /* ESSymbol */) {
                type = globalESSymbolType;
            }
            return type;
        }

function getApparentType ( type ) { if ( type . flags & 512 ) { do { type = getConstraintOfTypeParameter ( type ) ; } while ( type && type . flags & 512 ) ; if ( ! type ) { type = emptyObjectType ; } } if ( type . flags & 258 ) { type = globalStringType ; } else if ( type . flags & 132 ) { type = globalNumberType ; } else if ( type . flags & 8 ) { type = globalBooleanType ; } else if ( type . flags & 16777216 ) { type = globalESSymbolType ; } return type ; }

For a type parameter, return the base constraint of the type parameter. For the string, number,
boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
type itself. Note that the apparent type of a union type is the union type itself.

For a type parameter return the base constraint of the type parameter . For the string number boolean and symbol primitive types return the corresponding object types . Otherwise return the type itself . Note that the apparent type of a union type is the union type itself .


function getPropertyOfType(type, name) {
            type = getApparentType(type);
            if (type.flags & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (ts.hasProperty(resolved.members, name)) {
                    var symbol = resolved.members[name];
                    if (symbolIsValue(symbol)) {
                        return symbol;
                    }
                }
                if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
                    var symbol = getPropertyOfObjectType(globalFunctionType, name);
                    if (symbol) {
                        return symbol;
                    }
                }
                return getPropertyOfObjectType(globalObjectType, name);
            }
            if (type.flags & 49152 /* UnionOrIntersection */) {
                return getPropertyOfUnionOrIntersectionType(type, name);
            }
            return undefined;
        }

function getPropertyOfType ( type , name ) { type = getApparentType ( type ) ; if ( type . flags & 80896 ) { var resolved = resolveStructuredTypeMembers ( type ) ; if ( ts . hasProperty ( resolved . members , name ) ) { var symbol = resolved . members [ name ] ; if ( symbolIsValue ( symbol ) ) { return symbol ; } } if ( resolved === anyFunctionType || resolved . callSignatures . length || resolved . constructSignatures . length ) { var symbol = getPropertyOfObjectType ( globalFunctionType , name ) ; if ( symbol ) { return symbol ; } } return getPropertyOfObjectType ( globalObjectType , name ) ; } if ( type . flags & 49152 ) { return getPropertyOfUnionOrIntersectionType ( type , name ) ; } return undefined ; }

Return the symbol for the property with the given name in the given type. Creates synthetic union properties when necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from Object and Function as appropriate.

Return the symbol for the property with the given name in the given type . Creates synthetic union properties when necessary maps primitive types and type parameters are to their apparent types and augments with properties from Object and Function as appropriate .


function getPropagatingFlagsOfTypes(types) {
            var result = 0;
            for (var _i = 0; _i < types.length; _i++) {
                var type = types[_i];
                result |= type.flags;
            }
            return result & 14680064 /* PropagatingFlags */;
        }

function getPropagatingFlagsOfTypes ( types ) { var result = 0 ; for ( var _i = 0 ; _i < types . length ; _i ++ ) { var type = types [ _i ] ; result |= type . flags ; } return result & 14680064 ; }

This function is used to propagate certain flags when creating new object type references and union types. It is only necessary to do so if a constituent type might be the undefined type, the null type, the type of an object literal or the anyFunctionType. This is because there are operations in the type checker that care about the presence of such types at arbitrary depth in a containing type.

This function is used to propagate certain flags when creating new object type references and union types . It is only necessary to do so if a constituent type might be the undefined type the null type the type of an object literal or the anyFunctionType . This is because there are operations in the type checker that care about the presence of such types at arbitrary depth in a containing type .


function getTypeFromClassOrInterfaceReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeParameters = type.localTypeParameters;
            if (typeParameters) {
                if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) {
                    error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */), typeParameters.length);
                    return unknownType;
                }
                // In a type reference, the outer type parameters of the referenced class or interface are automatically
                // supplied as type arguments and the type reference only specifies arguments for the local type parameters
                // of the class or interface.
                return createTypeReference(type, ts.concatenate(type.outerTypeParameters, ts.map(node.typeArguments, getTypeFromTypeNode)));
            }
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
                return unknownType;
            }
            return type;
        }

Get type from reference to class or interface


function getTypeFromTypeAliasReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            if (typeParameters) {
                if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) {
                    error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length);
                    return unknownType;
                }
                var typeArguments = ts.map(node.typeArguments, getTypeFromTypeNode);
                var id = getTypeListId(typeArguments);
                return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments)));
            }
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol));
                return unknownType;
            }
            return type;
        }

Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the declared type. Instantiations are cached using the type identities of the type arguments as the key.

Get type from reference to type alias . When a type alias is generic the declared type of the type alias may include references to the type parameters of the alias . We replace those with the actual type arguments by instantiating the declared type . Instantiations are cached using the type identities of the type arguments as the key .


function addTypesToSet(typeSet, types, typeSetKind) {
            for (var _i = 0; _i < types.length; _i++) {
                var type = types[_i];
                addTypeToSet(typeSet, type, typeSetKind);
            }
        }

function addTypesToSet ( typeSet , types , typeSetKind ) { for ( var _i = 0 ; _i < types . length ; _i ++ ) { var type = types [ _i ] ; addTypeToSet ( typeSet , type , typeSetKind ) ; } }

Add the given types to the given type set. Order is preserved, duplicates are removed, and nested types of the given kind are flattened into the set.

Add the given types to the given type set . Order is preserved duplicates are removed and nested types of the given kind are flattened into the set .


function isKnownProperty(type, name) {
                if (type.flags & 80896 /* ObjectType */) {
                    var resolved = resolveStructuredTypeMembers(type);
                    if (relation === assignableRelation && (type === globalObjectType || resolved.properties.length === 0) ||
                        resolved.stringIndexType || resolved.numberIndexType || getPropertyOfType(type, name)) {
                        return true;
                    }
                    return false;
                }
                if (type.flags & 49152 /* UnionOrIntersection */) {
                    for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                        var t = _a[_i];
                        if (isKnownProperty(t, name)) {
                            return true;
                        }
                    }
                    return false;
                }
                return true;
            }

function isKnownProperty ( type , name ) { if ( type . flags & 80896 ) { var resolved = resolveStructuredTypeMembers ( type ) ; if ( relation === assignableRelation && ( type === globalObjectType || resolved . properties . length === 0 ) || resolved . stringIndexType || resolved . numberIndexType || getPropertyOfType ( type , name ) ) { return true ; } return false ; } if ( type . flags & 49152 ) { for ( var _i = 0 , _a = type . types ; _i < _a . length ; _i ++ ) { var t = _a [ _i ] ; if ( isKnownProperty ( t , name ) ) { return true ; } } return false ; } return true ; }

Check if a property with the given name is known anywhere in the given type. In an object type, a property is considered known if the object type is empty and the check is for assignability, if the object type has index signatures, or if the property is actually declared in the object type. In a union or intersection type, a property is considered known if it is known in any constituent type.

Check if a property with the given name is known anywhere in the given type . In an object type a property is considered known if the object type is empty and the check is for assignability if the object type has index signatures or if the property is actually declared in the object type . In a union or intersection type a property is considered known if it is known in any constituent type .


function objectTypeRelatedTo(source, target, reportErrors) {
                if (overflow) {
                    return 0 /* False */;
                }
                var id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
                var related = relation[id];
                if (related !== undefined) {
                    // If we computed this relation already and it was failed and reported, or if we're not being asked to elaborate
                    // errors, we can use the cached value. Otherwise, recompute the relation
                    if (!elaborateErrors || (related === 3 /* FailedAndReported */)) {
                        return related === 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
                    }
                }
                if (depth > 0) {
                    for (var i = 0; i < depth; i++) {
                        // If source and target are already being compared, consider them related with assumptions
                        if (maybeStack[i][id]) {
                            return 1 /* Maybe */;
                        }
                    }
                    if (depth === 100) {
                        overflow = true;
                        return 0 /* False */;
                    }
                }
                else {
                    sourceStack = [];
                    targetStack = [];
                    maybeStack = [];
                    expandingFlags = 0;
                }
                sourceStack[depth] = source;
                targetStack[depth] = target;
                maybeStack[depth] = {};
                maybeStack[depth][id] = 1 /* Succeeded */;
                depth++;
                var saveExpandingFlags = expandingFlags;
                if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack, depth))
                    expandingFlags |= 1;
                if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack, depth))
                    expandingFlags |= 2;
                var result;
                if (expandingFlags === 3) {
                    result = 1 /* Maybe */;
                }
                else {
                    result = propertiesRelatedTo(source, target, reportErrors);
                    if (result) {
                        result &= signaturesRelatedTo(source, target, 0 /* Call */, reportErrors);
                        if (result) {
                            result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportErrors);
                            if (result) {
                                result &= stringIndexTypesRelatedTo(source, target, reportErrors);
                                if (result) {
                                    result &= numberIndexTypesRelatedTo(source, target, reportErrors);
                                }
                            }
                        }
                    }
                }
                expandingFlags = saveExpandingFlags;
                depth--;
                if (result) {
                    var maybeCache = maybeStack[depth];
                    // If result is definitely true, copy assumptions to global cache, else copy to next level up
                    var destinationCache = (result === -1 /* True */ || depth === 0) ? relation : maybeStack[depth - 1];
                    ts.copyMap(maybeCache, destinationCache);
                }
                else {
                    // A false result goes straight into global cache (when something is false under assumptions it
                    // will also be false without assumptions)
                    relation[id] = reportErrors ? 3 /* FailedAndReported */ : 2 /* Failed */;
                }
                return result;
            }

function objectTypeRelatedTo ( source , target , reportErrors ) { if ( overflow ) { return 0 ; } var id = relation !== identityRelation || source . id < target . id ? source . id + "," + target . id : target . id + "," + source . id ; var related = relation [ id ] ; if ( related !== undefined ) { if ( ! elaborateErrors || ( related === 3 ) ) { return related === 1 ? - 1 : 0 ; } } if ( depth > 0 ) { for ( var i = 0 ; i < depth ; i ++ ) { if ( maybeStack [ i ] [ id ] ) { return 1 ; } } if ( depth === 100 ) { overflow = true ; return 0 ; } } else { sourceStack = [ ] ; targetStack = [ ] ; maybeStack = [ ] ; expandingFlags = 0 ; } sourceStack [ depth ] = source ; targetStack [ depth ] = target ; maybeStack [ depth ] = { } ; maybeStack [ depth ] [ id ] = 1 ; depth ++ ; var saveExpandingFlags = expandingFlags ; if ( ! ( expandingFlags & 1 ) && isDeeplyNestedGeneric ( source , sourceStack , depth ) ) expandingFlags |= 1 ; if ( ! ( expandingFlags & 2 ) && isDeeplyNestedGeneric ( target , targetStack , depth ) ) expandingFlags |= 2 ; var result ; if ( expandingFlags === 3 ) { result = 1 ; } else { result = propertiesRelatedTo ( source , target , reportErrors ) ; if ( result ) { result &= signaturesRelatedTo ( source , target , 0 , reportErrors ) ; if ( result ) { result &= signaturesRelatedTo ( source , target , 1 , reportErrors ) ; if ( result ) { result &= stringIndexTypesRelatedTo ( source , target , reportErrors ) ; if ( result ) { result &= numberIndexTypesRelatedTo ( source , target , reportErrors ) ; } } } } } expandingFlags = saveExpandingFlags ; depth -- ; if ( result ) { var maybeCache = maybeStack [ depth ] ; var destinationCache = ( result === - 1 || depth === 0 ) ? relation : maybeStack [ depth - 1 ] ; ts . copyMap ( maybeCache , destinationCache ) ; } else { relation [ id ] = reportErrors ? 3 : 2 ; } return result ; }

Determine if two object types are related by structure. First, check if the result is already available in the global cache. Second, check if we have already started a comparison of the given two types in which case we assume the result to be true. Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion and issue an error. Otherwise, actually compare the structure of the two types.

Determine if two object types are related by structure . First check if the result is already available in the global cache . Second check if we have already started a comparison of the given two types in which case we assume the result to be true . Third check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are equal and infinitely expanding . Fourth if we have reached a depth of 100 nested comparisons assume we have runaway recursion and issue an error . Otherwise actually compare the structure of the two types .


function isDeeplyNestedGeneric(type, stack, depth) {
            // We track type references (created by createTypeReference) and instantiated types (created by instantiateType)
            if (type.flags & (4096 /* Reference */ | 131072 /* Instantiated */) && depth >= 5) {
                var symbol = type.symbol;
                var count = 0;
                for (var i = 0; i < depth; i++) {
                    var t = stack[i];
                    if (t.flags & (4096 /* Reference */ | 131072 /* Instantiated */) && t.symbol === symbol) {
                        count++;
                        if (count >= 5)
                            return true;
                    }
                }
            }
            return false;
        }

function isDeeplyNestedGeneric ( type , stack , depth ) { if ( type . flags & ( 4096 | 131072 ) && depth >= 5 ) { var symbol = type . symbol ; var count = 0 ; for ( var i = 0 ; i < depth ; i ++ ) { var t = stack [ i ] ; if ( t . flags & ( 4096 | 131072 ) && t . symbol === symbol ) { count ++ ; if ( count >= 5 ) return true ; } } } return false ; }

Return true if the given type is part of a deeply nested chain of generic instantiations. We consider this to be the case when structural type comparisons have been started for 10 or more instantiations of the same generic type. It is possible, though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 10 levels, but unequal at some level beyond that.

Return true if the given type is part of a deeply nested chain of generic instantiations . We consider this to be the case when structural type comparisons have been started for 10 or more instantiations of the same generic type . It is possible though highly unlikely for this test to be true in a situation where a chain of instantiations is not infinitely expanding . Effectively we will generate a false positive when two types are structurally equal to at least 10 levels but unequal at some level beyond that .


function isVariableAssignedWithin(symbol, node) {
            var links = getNodeLinks(node);
            if (links.assignmentChecks) {
                var cachedResult = links.assignmentChecks[symbol.id];
                if (cachedResult !== undefined) {
                    return cachedResult;
                }
            }
            else {
                links.assignmentChecks = {};
            }
            return links.assignmentChecks[symbol.id] = isAssignedIn(node);
            function isAssignedInBinaryExpression(node) {
                if (node.operatorToken.kind >= 56 /* FirstAssignment */ && node.operatorToken.kind <= 68 /* LastAssignment */) {
                    var n = node.left;
                    while (n.kind === 172 /* ParenthesizedExpression */) {
                        n = n.expression;
                    }
                    if (n.kind === 69 /* Identifier */ && getResolvedSymbol(n) === symbol) {
                        return true;
                    }
                }
                return ts.forEachChild(node, isAssignedIn);
            }
            function isAssignedInVariableDeclaration(node) {
                if (!ts.isBindingPattern(node.name) && getSymbolOfNode(node) === symbol && hasInitializer(node)) {
                    return true;
                }
                return ts.forEachChild(node, isAssignedIn);
            }
            function isAssignedIn(node) {
                switch (node.kind) {
                    case 181 /* BinaryExpression */:
                        return isAssignedInBinaryExpression(node);
                    case 211 /* VariableDeclaration */:
                    case 163 /* BindingElement */:
                        return isAssignedInVariableDeclaration(node);
                    case 161 /* ObjectBindingPattern */:
                    case 162 /* ArrayBindingPattern */:
                    case 164 /* ArrayLiteralExpression */:
                    case 165 /* ObjectLiteralExpression */:
                    case 166 /* PropertyAccessExpression */:
                    case 167 /* ElementAccessExpression */:
                    case 168 /* CallExpression */:
                    case 169 /* NewExpression */:
                    case 171 /* TypeAssertionExpression */:
                    case 189 /* AsExpression */:
                    case 172 /* ParenthesizedExpression */:
                    case 179 /* PrefixUnaryExpression */:
                    case 175 /* DeleteExpression */:
                    case 178 /* AwaitExpression */:
                    case 176 /* TypeOfExpression */:
                    case 177 /* VoidExpression */:
                    case 180 /* PostfixUnaryExpression */:
                    case 184 /* YieldExpression */:
                    case 182 /* ConditionalExpression */:
                    case 185 /* SpreadElementExpression */:
                    case 192 /* Block */:
                    case 193 /* VariableStatement */:
                    case 195 /* ExpressionStatement */:
                    case 196 /* IfStatement */:
                    case 197 /* DoStatement */:
                    case 198 /* WhileStatement */:
                    case 199 /* ForStatement */:
                    case 200 /* ForInStatement */:
                    case 201 /* ForOfStatement */:
                    case 204 /* ReturnStatement */:
                    case 205 /* WithStatement */:
                    case 206 /* SwitchStatement */:
                    case 241 /* CaseClause */:
                    case 242 /* DefaultClause */:
                    case 207 /* LabeledStatement */:
                    case 208 /* ThrowStatement */:
                    case 209 /* TryStatement */:
                    case 244 /* CatchClause */:
                    case 233 /* JsxElement */:
                    case 234 /* JsxSelfClosingElement */:
                    case 238 /* JsxAttribute */:
                    case 239 /* JsxSpreadAttribute */:
                    case 235 /* JsxOpeningElement */:
                    case 240 /* JsxExpression */:
                        return ts.forEachChild(node, isAssignedIn);
                }
                return false;
            }
        }

function isVariableAssignedWithin ( symbol , node ) { var links = getNodeLinks ( node ) ; if ( links . assignmentChecks ) { var cachedResult = links . assignmentChecks [ symbol . id ] ; if ( cachedResult !== undefined ) { return cachedResult ; } } else { links . assignmentChecks = { } ; } return links . assignmentChecks [ symbol . id ] = isAssignedIn ( node ) ; function isAssignedInBinaryExpression ( node ) { if ( node . operatorToken . kind >= 56 && node . operatorToken . kind <= 68 ) { var n = node . left ; while ( n . kind === 172 ) { n = n . expression ; } if ( n . kind === 69 && getResolvedSymbol ( n ) === symbol ) { return true ; } } return ts . forEachChild ( node , isAssignedIn ) ; } function isAssignedInVariableDeclaration ( node ) { if ( ! ts . isBindingPattern ( node . name ) && getSymbolOfNode ( node ) === symbol && hasInitializer ( node ) ) { return true ; } return ts . forEachChild ( node , isAssignedIn ) ; } function isAssignedIn ( node ) { switch ( node . kind ) { case 181 : return isAssignedInBinaryExpression ( node ) ; case 211 : case 163 : return isAssignedInVariableDeclaration ( node ) ; case 161 : case 162 : case 164 : case 165 : case 166 : case 167 : case 168 : case 169 : case 171 : case 189 : case 172 : case 179 : case 175 : case 178 : case 176 : case 177 : case 180 : case 184 : case 182 : case 185 : case 192 : case 193 : case 195 : case 196 : case 197 : case 198 : case 199 : case 200 : case 201 : case 204 : case 205 : case 206 : case 241 : case 242 : case 207 : case 208 : case 209 : case 244 : case 233 : case 234 : case 238 : case 239 : case 235 : case 240 : return ts . forEachChild ( node , isAssignedIn ) ; } return false ; } }

Check if a given variable is assigned within a given syntax node


function narrowType(type, expr, assumeTrue) {
                switch (expr.kind) {
                    case 168 /* CallExpression */:
                        return narrowTypeByTypePredicate(type, expr, assumeTrue);
                    case 172 /* ParenthesizedExpression */:
                        return narrowType(type, expr.expression, assumeTrue);
                    case 181 /* BinaryExpression */:
                        var operator = expr.operatorToken.kind;
                        if (operator === 32 /* EqualsEqualsEqualsToken */ || operator === 33 /* ExclamationEqualsEqualsToken */) {
                            return narrowTypeByEquality(type, expr, assumeTrue);
                        }
                        else if (operator === 51 /* AmpersandAmpersandToken */) {
                            return narrowTypeByAnd(type, expr, assumeTrue);
                        }
                        else if (operator === 52 /* BarBarToken */) {
                            return narrowTypeByOr(type, expr, assumeTrue);
                        }
                        else if (operator === 91 /* InstanceOfKeyword */) {
                            return narrowTypeByInstanceof(type, expr, assumeTrue);
                        }
                        break;
                    case 179 /* PrefixUnaryExpression */:
                        if (expr.operator === 49 /* ExclamationToken */) {
                            return narrowType(type, expr.operand, !assumeTrue);
                        }
                        break;
                }
                return type;
            }

function narrowType ( type , expr , assumeTrue ) { switch ( expr . kind ) { case 168 : return narrowTypeByTypePredicate ( type , expr , assumeTrue ) ; case 172 : return narrowType ( type , expr . expression , assumeTrue ) ; case 181 : var operator = expr . operatorToken . kind ; if ( operator === 32 || operator === 33 ) { return narrowTypeByEquality ( type , expr , assumeTrue ) ; } else if ( operator === 51 ) { return narrowTypeByAnd ( type , expr , assumeTrue ) ; } else if ( operator === 52 ) { return narrowTypeByOr ( type , expr , assumeTrue ) ; } else if ( operator === 91 ) { return narrowTypeByInstanceof ( type , expr , assumeTrue ) ; } break ; case 179 : if ( expr . operator === 49 ) { return narrowType ( type , expr . operand , ! assumeTrue ) ; } break ; } return type ; }

Narrow the given type based on the given expression having the assumed boolean value. The returned type will be a subtype or the same type as the argument.

Narrow the given type based on the given expression having the assumed boolean value . The returned type will be a subtype or the same type as the argument .


function getContextuallyTypedParameterType(parameter) {
            var func = parameter.parent;
            if (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) {
                if (isContextSensitive(func)) {
                    var contextualSignature = getContextualSignature(func);
                    if (contextualSignature) {
                        var funcHasRestParameters = ts.hasRestParameter(func);
                        var len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
                        var indexOfParameter = ts.indexOf(func.parameters, parameter);
                        if (indexOfParameter < len) {
                            return getTypeAtPosition(contextualSignature, indexOfParameter);
                        }
                        // If last parameter is contextually rest parameter get its type
                        if (funcHasRestParameters &&
                            indexOfParameter === (func.parameters.length - 1) &&
                            isRestParameterIndex(contextualSignature, func.parameters.length - 1)) {
                            return getTypeOfSymbol(ts.lastOrUndefined(contextualSignature.parameters));
                        }
                    }
                }
            }
            return undefined;
        }

function getContextuallyTypedParameterType ( parameter ) { var func = parameter . parent ; if ( isFunctionExpressionOrArrowFunction ( func ) || ts . isObjectLiteralMethod ( func ) ) { if ( isContextSensitive ( func ) ) { var contextualSignature = getContextualSignature ( func ) ; if ( contextualSignature ) { var funcHasRestParameters = ts . hasRestParameter ( func ) ; var len = func . parameters . length - ( funcHasRestParameters ? 1 : 0 ) ; var indexOfParameter = ts . indexOf ( func . parameters , parameter ) ; if ( indexOfParameter < len ) { return getTypeAtPosition ( contextualSignature , indexOfParameter ) ; } if ( funcHasRestParameters && indexOfParameter === ( func . parameters . length - 1 ) && isRestParameterIndex ( contextualSignature , func . parameters . length - 1 ) ) { return getTypeOfSymbol ( ts . lastOrUndefined ( contextualSignature . parameters ) ) ; } } } } return undefined ; }

Return contextual type of parameter or undefined if no contextual type is available


function getContextualTypeForInitializerExpression(node) {
            var declaration = node.parent;
            if (node === declaration.initializer) {
                if (declaration.type) {
                    return getTypeFromTypeNode(declaration.type);
                }
                if (declaration.kind === 138 /* Parameter */) {
                    var type = getContextuallyTypedParameterType(declaration);
                    if (type) {
                        return type;
                    }
                }
                if (ts.isBindingPattern(declaration.name)) {
                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true);
                }
            }
            return undefined;
        }

In a variable, parameter or property declaration with a type annotation, the contextual type of an initializer expression is the type of the variable, parameter or property. Otherwise, in a parameter declaration of a contextually typed function expression, the contextual type of an initializer expression is the contextual type of the parameter. Otherwise, in a variable or parameter declaration with a binding pattern name, the contextual type of an initializer expression is the type implied by the binding pattern.

In a variable parameter or property declaration with a type annotation the contextual type of an initializer expression is the type of the variable parameter or property . Otherwise in a parameter declaration of a contextually typed function expression the contextual type of an initializer expression is the contextual type of the parameter . Otherwise in a variable or parameter declaration with a binding pattern name the contextual type of an initializer expression is the type implied by the binding pattern .


function applyToContextualType(type, mapper) {
            if (!(type.flags & 16384 /* Union */)) {
                return mapper(type);
            }
            var types = type.types;
            var mappedType;
            var mappedTypes;
            for (var _i = 0; _i < types.length; _i++) {
                var current = types[_i];
                var t = mapper(current);
                if (t) {
                    if (!mappedType) {
                        mappedType = t;
                    }
                    else if (!mappedTypes) {
                        mappedTypes = [mappedType, t];
                    }
                    else {
                        mappedTypes.push(t);
                    }
                }
            }
            return mappedTypes ? getUnionType(mappedTypes) : mappedType;
        }

function applyToContextualType ( type , mapper ) { if ( ! ( type . flags & 16384 ) ) { return mapper ( type ) ; } var types = type . types ; var mappedType ; var mappedTypes ; for ( var _i = 0 ; _i < types . length ; _i ++ ) { var current = types [ _i ] ; var t = mapper ( current ) ; if ( t ) { if ( ! mappedType ) { mappedType = t ; } else if ( ! mappedTypes ) { mappedTypes = [ mappedType , t ] ; } else { mappedTypes . push ( t ) ; } } } return mappedTypes ? getUnionType ( mappedTypes ) : mappedType ; }

Apply a mapping function to a contextual type and return the resulting type. If the contextual type is a union type, the mapping function is applied to each constituent type and a union of the resulting types is returned.

Apply a mapping function to a contextual type and return the resulting type . If the contextual type is a union type the mapping function is applied to each constituent type and a union of the resulting types is returned .


function contextualTypeHasIndexSignature(type, kind) {
            return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, function (t) { return getIndexTypeOfStructuredType(t, kind); }) : getIndexTypeOfStructuredType(type, kind));
        }

function contextualTypeHasIndexSignature ( type , kind ) { return ! ! ( type . flags & 16384 ? ts . forEach ( type . types , function ( t ) { return getIndexTypeOfStructuredType ( t , kind ) ; } ) : getIndexTypeOfStructuredType ( type , kind ) ) ; }

Return true if the given contextual type provides an index signature of the given kind


function getContextualTypeForObjectLiteralMethod(node) {
            ts.Debug.assert(ts.isObjectLiteralMethod(node));
            if (isInsideWithStatementBody(node)) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            return getContextualTypeForObjectLiteralElement(node);
        }

In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one exists. Otherwise, it is the type of the string index signature in T, if one exists.

In an object literal contextually typed by a type T the contextual type of a property assignment is the type of the matching property in T if one exists . Otherwise it is the type of the numeric index signature in T if one exists . Otherwise it is the type of the string index signature in T if one exists .


function getContextualTypeForElementExpression(node) {
            var arrayLiteral = node.parent;
            var type = getContextualType(arrayLiteral);
            if (type) {
                var index = ts.indexOf(arrayLiteral.elements, node);
                return getTypeOfPropertyOfContextualType(type, "" + index)
                    || getIndexTypeOfContextualType(type, 1 /* Number */)
                    || (languageVersion >= 2 /* ES6 */ ? getElementTypeOfIterable(type, /*errorNode*/ undefined) : undefined);
            }
            return undefined;
        }

function getContextualTypeForElementExpression ( node ) { var arrayLiteral = node . parent ; var type = getContextualType ( arrayLiteral ) ; if ( type ) { var index = ts . indexOf ( arrayLiteral . elements , node ) ; return getTypeOfPropertyOfContextualType ( type , "" + index ) || getIndexTypeOfContextualType ( type , 1 ) || ( languageVersion >= 2 ? getElementTypeOfIterable ( type , undefined ) : undefined ) ; } return undefined ; }

In an array literal contextually typed by a type T, the contextual type of an element expression at index N is the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature, it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated type of T.

In an array literal contextually typed by a type T the contextual type of an element expression at index N is the type of the property with the numeric name N in T if one exists . Otherwise if T has a numeric index signature it is the type of the numeric index signature in T . Otherwise in ES6 and higher the contextual type is the iterated type of T .


function getNonGenericSignature(type) {
            var signatures = getSignaturesOfStructuredType(type, 0 /* Call */);
            if (signatures.length === 1) {
                var signature = signatures[0];
                if (!signature.typeParameters) {
                    return signature;
                }
            }
        }

function getNonGenericSignature ( type ) { var signatures = getSignaturesOfStructuredType ( type , 0 ) ; if ( signatures . length === 1 ) { var signature = signatures [ 0 ] ; if ( ! signature . typeParameters ) { return signature ; } } }

If the given type is an object or union type, if that type has a single signature, and if that signature is non-generic, return the signature. Otherwise return undefined.

If the given type is an object or union type if that type has a single signature and if that signature is non - generic return the signature . Otherwise return undefined .


function getContextualSignature(node) {
            ts.Debug.assert(node.kind !== 143 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var type = ts.isObjectLiteralMethod(node)
                ? getContextualTypeForObjectLiteralMethod(node)
                : getContextualType(node);
            if (!type) {
                return undefined;
            }
            if (!(type.flags & 16384 /* Union */)) {
                return getNonGenericSignature(type);
            }
            var signatureList;
            var types = type.types;
            for (var _i = 0; _i < types.length; _i++) {
                var current = types[_i];
                var signature = getNonGenericSignature(current);
                if (signature) {
                    if (!signatureList) {
                        // This signature will contribute to contextual union signature
                        signatureList = [signature];
                    }
                    else if (!compareSignatures(signatureList[0], signature, /*partialMatch*/ false, /*ignoreReturnTypes*/ true, compareTypes)) {
                        // Signatures aren't identical, do not use
                        return undefined;
                    }
                    else {
                        // Use this signature for contextual union signature
                        signatureList.push(signature);
                    }
                }
            }
            // Result is union of signatures collected (return type is union of return types of this signature set)
            var result;
            if (signatureList) {
                result = cloneSignature(signatureList[0]);
                // Clear resolved return type we possibly got from cloneSignature
                result.resolvedReturnType = undefined;
                result.unionSignatures = signatureList;
            }
            return result;
        }

function getContextualSignature ( node ) { ts . Debug . assert ( node . kind !== 143 || ts . isObjectLiteralMethod ( node ) ) ; var type = ts . isObjectLiteralMethod ( node ) ? getContextualTypeForObjectLiteralMethod ( node ) : getContextualType ( node ) ; if ( ! type ) { return undefined ; } if ( ! ( type . flags & 16384 ) ) { return getNonGenericSignature ( type ) ; } var signatureList ; var types = type . types ; for ( var _i = 0 ; _i < types . length ; _i ++ ) { var current = types [ _i ] ; var signature = getNonGenericSignature ( current ) ; if ( signature ) { if ( ! signatureList ) { signatureList = [ signature ] ; } else if ( ! compareSignatures ( signatureList [ 0 ] , signature , false , true , compareTypes ) ) { return undefined ; } else { signatureList . push ( signature ) ; } } } var result ; if ( signatureList ) { result = cloneSignature ( signatureList [ 0 ] ) ; result . resolvedReturnType = undefined ; result . unionSignatures = signatureList ; } return result ; }

Return the contextual signature for a given expression node. A contextual type provides a contextual signature if it has a single call signature and if that call signature is non-generic. If the contextual type is a union type, get the signature from each type possible and if they are all identical ignoring their return type, the result is same signature but with return type as union type of return types from these signatures

Return the contextual signature for a given expression node . A contextual type provides a contextual signature if it has a single call signature and if that call signature is non - generic . If the contextual type is a union type get the signature from each type possible and if they are all identical ignoring their return type the result is same signature but with return type as union type of return types from these signatures


function getJsxAttributePropertySymbol(attrib) {
            var attributesType = getJsxElementAttributesType(attrib.parent);
            var prop = getPropertyOfType(attributesType, attrib.name.text);
            return prop || unknownSymbol;
        }

function getJsxAttributePropertySymbol ( attrib ) { var attributesType = getJsxElementAttributesType ( attrib . parent ) ; var prop = getPropertyOfType ( attributesType , attrib . name . text ) ; return prop || unknownSymbol ; }

Given a JSX attribute, returns the symbol for the corresponds property
of the element attributes type. Will return unknownSymbol for attributes
that have no matching element attributes type property.

Given a JSX attribute returns the symbol for the corresponds property of the element attributes type . Will return unknownSymbol for attributes that have no matching element attributes type property .


function checkClassPropertyAccess(node, left, type, prop) {
            var flags = getDeclarationFlagsFromSymbol(prop);
            var declaringClass = getDeclaredTypeOfSymbol(prop.parent);
            if (left.kind === 95 /* SuperKeyword */) {
                var errorNode = node.kind === 166 /* PropertyAccessExpression */ ?
                    node.name :
                    node.right;
                // TS 1.0 spec (April 2014): 4.8.2
                // - In a constructor, instance member function, instance member accessor, or
                //   instance member variable initializer where this references a derived class instance,
                //   a super property access is permitted and must specify a public instance member function of the base class.
                // - In a static member function or static member accessor
                //   where this references the constructor function object of a derived class,
                //   a super property access is permitted and must specify a public static member function of the base class.
                if (getDeclarationKindFromSymbol(prop) !== 143 /* MethodDeclaration */) {
                    // `prop` refers to a *property* declared in the super class
                    // rather than a *method*, so it does not satisfy the above criteria.
                    error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                    return false;
                }
                if (flags & 256 /* Abstract */) {
                    // A method cannot be accessed in a super property access if the method is abstract.
                    // This error could mask a private property access error. But, a member
                    // cannot simultaneously be private and abstract, so this will trigger an
                    // additional error elsewhere.
                    error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(declaringClass));
                    return false;
                }
            }
            // Public properties are otherwise accessible.
            if (!(flags & (32 /* Private */ | 64 /* Protected */))) {
                return true;
            }
            // Property is known to be private or protected at this point
            // Get the declaring and enclosing class instance types
            var enclosingClassDeclaration = ts.getContainingClass(node);
            var enclosingClass = enclosingClassDeclaration ? getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined;
            // Private property is accessible if declaring and enclosing class are the same
            if (flags & 32 /* Private */) {
                if (declaringClass !== enclosingClass) {
                    error(node, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(declaringClass));
                    return false;
                }
                return true;
            }
            // Property is known to be protected at this point
            // All protected properties of a supertype are accessible in a super access
            if (left.kind === 95 /* SuperKeyword */) {
                return true;
            }
            // A protected property is accessible in the declaring class and classes derived from it
            if (!enclosingClass || !hasBaseType(enclosingClass, declaringClass)) {
                error(node, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(declaringClass));
                return false;
            }
            // No further restrictions for static properties
            if (flags & 128 /* Static */) {
                return true;
            }
            // An instance property must be accessed through an instance of the enclosing class
            if (type.flags & 33554432 /* ThisType */) {
                // get the original type -- represented as the type constraint of the 'this' type
                type = getConstraintOfTypeParameter(type);
            }
            // TODO: why is the first part of this check here?
            if (!(getTargetType(type).flags & (1024 /* Class */ | 2048 /* Interface */) && hasBaseType(type, enclosingClass))) {
                error(node, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                return false;
            }
            return true;
        }

Check whether the requested property access is valid.
Returns true if node is a valid property access, and false otherwise.
@param node The node to be checked.
@param left The left hand side of the property access (e.g.: the super in `super.foo`).
@param type The type of left.
@param prop The symbol for the right hand side of the property access.

Check whether the requested property access is valid . Returns true if node is a valid property access and false otherwise .


function getPropertyNameForIndexedAccess(indexArgumentExpression, indexArgumentType) {
            if (indexArgumentExpression.kind === 9 /* StringLiteral */ || indexArgumentExpression.kind === 8 /* NumericLiteral */) {
                return indexArgumentExpression.text;
            }
            if (indexArgumentExpression.kind === 167 /* ElementAccessExpression */ || indexArgumentExpression.kind === 166 /* PropertyAccessExpression */) {
                var value = getConstantValue(indexArgumentExpression);
                if (value !== undefined) {
                    return value.toString();
                }
            }
            if (checkThatExpressionIsProperSymbolReference(indexArgumentExpression, indexArgumentType, /*reportError*/ false)) {
                var rightHandSideName = indexArgumentExpression.name.text;
                return ts.getPropertyNameForKnownSymbolName(rightHandSideName);
            }
            return undefined;
        }

If indexArgumentExpression is a string literal or number literal, returns its text.
If indexArgumentExpression is a constant value, returns its string value.
If indexArgumentExpression is a well known symbol, returns the property name corresponding
to this symbol, as long as it is a proper symbol reference.
Otherwise, returns undefined.

If indexArgumentExpression is a string literal or number literal returns its text . If indexArgumentExpression is a constant value returns its string value . If indexArgumentExpression is a well known symbol returns the property name corresponding to this symbol as long as it is a proper symbol reference . Otherwise returns undefined .


function getSingleCallSignature(type) {
            if (type.flags & 80896 /* ObjectType */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 &&
                    resolved.properties.length === 0 && !resolved.stringIndexType && !resolved.numberIndexType) {
                    return resolved.callSignatures[0];
                }
            }
            return undefined;
        }

function getSingleCallSignature ( type ) { if ( type . flags & 80896 ) { var resolved = resolveStructuredTypeMembers ( type ) ; if ( resolved . callSignatures . length === 1 && resolved . constructSignatures . length === 0 && resolved . properties . length === 0 && ! resolved . stringIndexType && ! resolved . numberIndexType ) { return resolved . callSignatures [ 0 ] ; } } return undefined ; }

If type has a single call signature and no other members, return that signature. Otherwise, return undefined.

If type has a single call signature and no other members return that signature . Otherwise return undefined .


function getEffectiveCallArguments(node) {
            var args;
            if (node.kind === 170 /* TaggedTemplateExpression */) {
                var template = node.template;
                args = [undefined];
                if (template.kind === 183 /* TemplateExpression */) {
                    ts.forEach(template.templateSpans, function (span) {
                        args.push(span.expression);
                    });
                }
            }
            else if (node.kind === 139 /* Decorator */) {
                // For a decorator, we return undefined as we will determine
                // the number and types of arguments for a decorator using
                // `getEffectiveArgumentCount` and `getEffectiveArgumentType` below.
                return undefined;
            }
            else {
                args = node.arguments || emptyArray;
            }
            return args;
        }

function getEffectiveCallArguments ( node ) { var args ; if ( node . kind === 170 ) { var template = node . template ; args = [ undefined ] ; if ( template . kind === 183 ) { ts . forEach ( template . templateSpans , function ( span ) { args . push ( span . expression ) ; } ) ; } } else if ( node . kind === 139 ) { return undefined ; } else { args = node . arguments || emptyArray ; } return args ; }

Returns the effective arguments for an expression that works like a function invocation.

If 'node' is a CallExpression or a NewExpression, then its argument list is returned.
If 'node' is a TaggedTemplateExpression, a new argument list is constructed from the substitution
expressions, where the first element of the list is `undefined`.
If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types
will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`.

Returns the effective arguments for an expression that works like a function invocation .


function getEffectiveDecoratorArgumentType(node, argIndex) {
            if (argIndex === 0) {
                return getEffectiveDecoratorFirstArgumentType(node.parent);
            }
            else if (argIndex === 1) {
                return getEffectiveDecoratorSecondArgumentType(node.parent);
            }
            else if (argIndex === 2) {
                return getEffectiveDecoratorThirdArgumentType(node.parent);
            }
            ts.Debug.fail("Decorators should not have a fourth synthetic argument.");
            return unknownType;
        }

Returns the effective argument type for the provided argument to a decorator.

Returns the effective argument type for the provided argument to a decorator .


function getEffectiveArgumentType(node, argIndex, arg) {
            // Decorators provide special arguments, a tagged template expression provides
            // a special first argument, and string literals get string literal types
            // unless we're reporting errors
            if (node.kind === 139 /* Decorator */) {
                return getEffectiveDecoratorArgumentType(node, argIndex);
            }
            else if (argIndex === 0 && node.kind === 170 /* TaggedTemplateExpression */) {
                return globalTemplateStringsArrayType;
            }
            // This is not a synthetic argument, so we return 'undefined'
            // to signal that the caller needs to check the argument.
            return undefined;
        }

function getEffectiveArgumentType ( node , argIndex , arg ) { if ( node . kind === 139 ) { return getEffectiveDecoratorArgumentType ( node , argIndex ) ; } else if ( argIndex === 0 && node . kind === 170 ) { return globalTemplateStringsArrayType ; } return undefined ; }

Gets the effective argument type for an argument in a call expression.

Gets the effective argument type for an argument in a call expression .


function getEffectiveArgument(node, args, argIndex) {
            // For a decorator or the first argument of a tagged template expression we return undefined.
            if (node.kind === 139 /* Decorator */ ||
                (argIndex === 0 && node.kind === 170 /* TaggedTemplateExpression */)) {
                return undefined;
            }
            return args[argIndex];
        }

function getEffectiveArgument ( node , args , argIndex ) { if ( node . kind === 139 || ( argIndex === 0 && node . kind === 170 ) ) { return undefined ; } return args [ argIndex ] ; }

Gets the effective argument expression for an argument in a call expression.

Gets the effective argument expression for an argument in a call expression .


function getEffectiveArgumentErrorNode(node, argIndex, arg) {
            if (node.kind === 139 /* Decorator */) {
                // For a decorator, we use the expression of the decorator for error reporting.
                return node.expression;
            }
            else if (argIndex === 0 && node.kind === 170 /* TaggedTemplateExpression */) {
                // For a the first argument of a tagged template expression, we use the template of the tag for error reporting.
                return node.template;
            }
            else {
                return arg;
            }
        }

function getEffectiveArgumentErrorNode ( node , argIndex , arg ) { if ( node . kind === 139 ) { return node . expression ; } else if ( argIndex === 0 && node . kind === 170 ) { return node . template ; } else { return arg ; } }

Gets the error node to use when reporting errors for an effective argument.

Gets the error node to use when reporting errors for an effective argument .


function getDiagnosticHeadMessageForDecoratorResolution(node) {
            switch (node.parent.kind) {
                case 214 /* ClassDeclaration */:
                case 186 /* ClassExpression */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
                case 138 /* Parameter */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
                case 141 /* PropertyDeclaration */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
                case 143 /* MethodDeclaration */:
                case 145 /* GetAccessor */:
                case 146 /* SetAccessor */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression;
            }
        }

Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.

Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression .


function resolveDecorator(node, candidatesOutArray) {
            var funcType = checkExpression(node.expression);
            var apparentType = getApparentType(funcType);
            if (apparentType === unknownType) {
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            if (funcType === anyType || (!callSignatures.length && !(funcType.flags & 16384 /* Union */) && isTypeAssignableTo(funcType, globalFunctionType))) {
                return resolveUntypedCall(node);
            }
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            if (!callSignatures.length) {
                var errorInfo;
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
                errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage);
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, errorInfo));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, headMessage);
        }

Resolves a decorator as if it were a call expression.

Resolves a decorator as if it were a call expression .


function getResolvedSignature(node, candidatesOutArray) {
            var links = getNodeLinks(node);
            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
            // However, it is possible that either candidatesOutArray was not passed in the first time,
            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
            // to correctly fill the candidatesOutArray.
            if (!links.resolvedSignature || candidatesOutArray) {
                links.resolvedSignature = anySignature;
                if (node.kind === 168 /* CallExpression */) {
                    links.resolvedSignature = resolveCallExpression(node, candidatesOutArray);
                }
                else if (node.kind === 169 /* NewExpression */) {
                    links.resolvedSignature = resolveNewExpression(node, candidatesOutArray);
                }
                else if (node.kind === 170 /* TaggedTemplateExpression */) {
                    links.resolvedSignature = resolveTaggedTemplateExpression(node, candidatesOutArray);
                }
                else if (node.kind === 139 /* Decorator */) {
                    links.resolvedSignature = resolveDecorator(node, candidatesOutArray);
                }
                else {
                    ts.Debug.fail("Branch in 'getResolvedSignature' should be unreachable.");
                }
            }
            return links.resolvedSignature;
        }

candidatesOutArray is passed by signature help in the language service, and collectCandidates must fill it up with the appropriate candidate signatures

candidatesOutArray is passed by signature help in the language service and collectCandidates must fill it up with the appropriate candidate signatures


function checkCallExpression(node) {
            // Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
            checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node, node.arguments);
            var signature = getResolvedSignature(node);
            if (node.expression.kind === 95 /* SuperKeyword */) {
                return voidType;
            }
            if (node.kind === 169 /* NewExpression */) {
                var declaration = signature.declaration;
                if (declaration &&
                    declaration.kind !== 144 /* Constructor */ &&
                    declaration.kind !== 148 /* ConstructSignature */ &&
                    declaration.kind !== 153 /* ConstructorType */) {
                    // When resolved signature is a call signature (and not a construct signature) the result type is any
                    if (compilerOptions.noImplicitAny) {
                        error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                    }
                    return anyType;
                }
            }
            return getReturnTypeOfSignature(signature);
        }

Syntactically and semantically checks a call or new expression.
@param node The call/new expression to be checked.
@returns On success, the expression's signature's return type. On failure, anyType.

Syntactically and semantically checks a call or new expression .


function assignBindingElementTypes(node) {
            if (ts.isBindingPattern(node.name)) {
                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (element.kind !== 187 /* OmittedExpression */) {
                        if (element.name.kind === 69 /* Identifier */) {
                            getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
                        }
                        assignBindingElementTypes(element);
                    }
                }
            }
        }

function assignBindingElementTypes ( node ) { if ( ts . isBindingPattern ( node . name ) ) { for ( var _i = 0 , _a = node . name . elements ; _i < _a . length ; _i ++ ) { var element = _a [ _i ] ; if ( element . kind !== 187 ) { if ( element . name . kind === 69 ) { getSymbolLinks ( getSymbolOfNode ( element ) ) . type = getTypeForBindingElement ( element ) ; } assignBindingElementTypes ( element ) ; } } } }

When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push the destructured type into the contained binding elements.

When contextual typing assigns a type to a parameter that contains a binding pattern we also need to push the destructured type into the contained binding elements .


function checkTypeParameter(node) {
            // Grammar Checking
            if (node.expression) {
                grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
            }
            checkSourceElement(node.constraint);
            if (produceDiagnostics) {
                checkTypeParameterHasIllegalReferencesInConstraint(node);
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
            }
            // TODO: Check multiple declarations are identical
        }


function getPromisedType(promise) {
            //
            //  { // promise
            //      then( // thenFunction
            //          onfulfilled: ( // onfulfilledParameterType
            //              value: T // valueParameterType
            //          ) => any
            //      ): any;
            //  }
            //
            if (promise.flags & 1 /* Any */) {
                return undefined;
            }
            if ((promise.flags & 4096 /* Reference */) && promise.target === tryGetGlobalPromiseType()) {
                return promise.typeArguments[0];
            }
            var globalPromiseLikeType = getInstantiatedGlobalPromiseLikeType();
            if (globalPromiseLikeType === emptyObjectType || !isTypeAssignableTo(promise, globalPromiseLikeType)) {
                return undefined;
            }
            var thenFunction = getTypeOfPropertyOfType(promise, "then");
            if (thenFunction && (thenFunction.flags & 1 /* Any */)) {
                return undefined;
            }
            var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : emptyArray;
            if (thenSignatures.length === 0) {
                return undefined;
            }
            var onfulfilledParameterType = getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature));
            if (onfulfilledParameterType.flags & 1 /* Any */) {
                return undefined;
            }
            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
            if (onfulfilledParameterSignatures.length === 0) {
                return undefined;
            }
            var valueParameterType = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature));
            return valueParameterType;
        }

function getPromisedType ( promise ) { if ( promise . flags & 1 ) { return undefined ; } if ( ( promise . flags & 4096 ) && promise . target === tryGetGlobalPromiseType ( ) ) { return promise . typeArguments [ 0 ] ; } var globalPromiseLikeType = getInstantiatedGlobalPromiseLikeType ( ) ; if ( globalPromiseLikeType === emptyObjectType || ! isTypeAssignableTo ( promise , globalPromiseLikeType ) ) { return undefined ; } var thenFunction = getTypeOfPropertyOfType ( promise , "then" ) ; if ( thenFunction && ( thenFunction . flags & 1 ) ) { return undefined ; } var thenSignatures = thenFunction ? getSignaturesOfType ( thenFunction , 0 ) : emptyArray ; if ( thenSignatures . length === 0 ) { return undefined ; } var onfulfilledParameterType = getUnionType ( ts . map ( thenSignatures , getTypeOfFirstParameterOfSignature ) ) ; if ( onfulfilledParameterType . flags & 1 ) { return undefined ; } var onfulfilledParameterSignatures = getSignaturesOfType ( onfulfilledParameterType , 0 ) ; if ( onfulfilledParameterSignatures . length === 0 ) { return undefined ; } var valueParameterType = getUnionType ( ts . map ( onfulfilledParameterSignatures , getTypeOfFirstParameterOfSignature ) ) ; return valueParameterType ; }

Gets the "promised type" of a promise.
@param type The type of the promise.
@remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.


function checkDecorator(node) {
            var signature = getResolvedSignature(node);
            var returnType = getReturnTypeOfSignature(signature);
            if (returnType.flags & 1 /* Any */) {
                return;
            }
            var expectedReturnType;
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            var errorInfo;
            switch (node.parent.kind) {
                case 214 /* ClassDeclaration */:
                    var classSymbol = getSymbolOfNode(node.parent);
                    var classConstructorType = getTypeOfSymbol(classSymbol);
                    expectedReturnType = getUnionType([classConstructorType, voidType]);
                    break;
                case 138 /* Parameter */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any);
                    break;
                case 141 /* PropertyDeclaration */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any);
                    break;
                case 143 /* MethodDeclaration */:
                case 145 /* GetAccessor */:
                case 146 /* SetAccessor */:
                    var methodType = getTypeOfNode(node.parent);
                    var descriptorType = createTypedPropertyDescriptorType(methodType);
                    expectedReturnType = getUnionType([descriptorType, voidType]);
                    break;
            }
            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, errorInfo);
        }


function checkTypeNodeAsExpression(node) {
            // When we are emitting type metadata for decorators, we need to try to check the type
            // as if it were an expression so that we can emit the type in a value position when we
            // serialize the type metadata.
            if (node && node.kind === 151 /* TypeReference */) {
                var root = getFirstIdentifier(node.typeName);
                var meaning = root.parent.kind === 151 /* TypeReference */ ? 793056 /* Type */ : 1536 /* Namespace */;
                // Resolve type so we know which symbol is referenced
                var rootSymbol = resolveName(root, root.text, meaning | 8388608 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
                // Resolved symbol is alias
                if (rootSymbol && rootSymbol.flags & 8388608 /* Alias */) {
                    var aliasTarget = resolveAlias(rootSymbol);
                    // If alias has value symbol - mark alias as referenced
                    if (aliasTarget.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
                        markAliasSymbolAsReferenced(rootSymbol);
                    }
                }
            }
        }

function checkTypeNodeAsExpression ( node ) { if ( node && node . kind === 151 ) { var root = getFirstIdentifier ( node . typeName ) ; var meaning = root . parent . kind === 151 ? 793056 : 1536 ; var rootSymbol = resolveName ( root , root . text , meaning | 8388608 , undefined , undefined ) ; if ( rootSymbol && rootSymbol . flags & 8388608 ) { var aliasTarget = resolveAlias ( rootSymbol ) ; if ( aliasTarget . flags & 107455 && ! isConstEnumOrConstEnumOnlyModule ( resolveAlias ( rootSymbol ) ) ) { markAliasSymbolAsReferenced ( rootSymbol ) ; } } } }

Checks a type reference node as an expression.

Checks a type reference node as an expression .


function checkTypeAnnotationAsExpression(node) {
            switch (node.kind) {
                case 141 /* PropertyDeclaration */:
                    checkTypeNodeAsExpression(node.type);
                    break;
                case 138 /* Parameter */:
                    checkTypeNodeAsExpression(node.type);
                    break;
                case 143 /* MethodDeclaration */:
                    checkTypeNodeAsExpression(node.type);
                    break;
                case 145 /* GetAccessor */:
                    checkTypeNodeAsExpression(node.type);
                    break;
                case 146 /* SetAccessor */:
                    checkTypeNodeAsExpression(ts.getSetAccessorTypeAnnotationNode(node));
                    break;
            }
        }

function checkTypeAnnotationAsExpression ( node ) { switch ( node . kind ) { case 141 : checkTypeNodeAsExpression ( node . type ) ; break ; case 138 : checkTypeNodeAsExpression ( node . type ) ; break ; case 143 : checkTypeNodeAsExpression ( node . type ) ; break ; case 145 : checkTypeNodeAsExpression ( node . type ) ; break ; case 146 : checkTypeNodeAsExpression ( ts . getSetAccessorTypeAnnotationNode ( node ) ) ; break ; } }

Checks the type annotation of an accessor declaration or property declaration as
an expression if it is a type reference to a type with a value declaration.

Checks the type annotation of an accessor declaration or property declaration as an expression if it is a type reference to a type with a value declaration .


function checkDecorators(node) {
            if (!node.decorators) {
                return;
            }
            // skip this check for nodes that cannot have decorators. These should have already had an error reported by
            // checkGrammarDecorators.
            if (!ts.nodeCanBeDecorated(node)) {
                return;
            }
            if (!compilerOptions.experimentalDecorators) {
                error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalDecorators_to_remove_this_warning);
            }
            if (compilerOptions.emitDecoratorMetadata) {
                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
                switch (node.kind) {
                    case 214 /* ClassDeclaration */:
                        var constructor = ts.getFirstConstructorWithBody(node);
                        if (constructor) {
                            checkParameterTypeAnnotationsAsExpressions(constructor);
                        }
                        break;
                    case 143 /* MethodDeclaration */:
                        checkParameterTypeAnnotationsAsExpressions(node);
                    // fall-through
                    case 146 /* SetAccessor */:
                    case 145 /* GetAccessor */:
                    case 141 /* PropertyDeclaration */:
                    case 138 /* Parameter */:
                        checkTypeAnnotationAsExpression(node);
                        break;
                }
            }
            emitDecorate = true;
            if (node.kind === 138 /* Parameter */) {
                emitParam = true;
            }
            ts.forEach(node.decorators, checkDecorator);
        }


function checkIfThisIsCapturedInEnclosingScope(node) {
            var current = node;
            while (current) {
                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                    var isDeclaration_1 = node.kind !== 69 /* Identifier */;
                    if (isDeclaration_1) {
                        error(node.name, ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
                    }
                    return;
                }
                current = current.parent;
            }
        }

this function will run after checking the source file so 'CaptureThis' is correct for all nodes

this function will run after checking the source file so CaptureThis is correct for all nodes


function checkParameterInitializer(node) {
            if (ts.getRootDeclaration(node).kind !== 138 /* Parameter */) {
                return;
            }
            var func = ts.getContainingFunction(node);
            visit(node.initializer);
            function visit(n) {
                if (n.kind === 69 /* Identifier */) {
                    var referencedSymbol = getNodeLinks(n).resolvedSymbol;
                    // check FunctionLikeDeclaration.locals (stores parameters\function local variable)
                    // if it contains entry with a specified name and if this entry matches the resolved symbol
                    if (referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol(func.locals, referencedSymbol.name, 107455 /* Value */) === referencedSymbol) {
                        if (referencedSymbol.valueDeclaration.kind === 138 /* Parameter */) {
                            if (referencedSymbol.valueDeclaration === node) {
                                error(n, ts.Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, ts.declarationNameToString(node.name));
                                return;
                            }
                            if (referencedSymbol.valueDeclaration.pos < node.pos) {
                                // legal case - parameter initializer references some parameter strictly on left of current parameter declaration
                                return;
                            }
                        }
                        error(n, ts.Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(node.name), ts.declarationNameToString(n));
                    }
                }
                else {
                    ts.forEachChild(n, visit);
                }
            }
        }

Check that a parameter initializer contains no references to parameters declared to the right of itself


function checkVariableLikeDeclaration(node) {
            checkDecorators(node);
            checkSourceElement(node.type);
            // For a computed property, just check the initializer and exit
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 136 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
                if (node.initializer) {
                    checkExpressionCached(node.initializer);
                }
            }
            // For a binding pattern, check contained binding elements
            if (ts.isBindingPattern(node.name)) {
                ts.forEach(node.name.elements, checkSourceElement);
            }
            // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
            if (node.initializer && ts.getRootDeclaration(node).kind === 138 /* Parameter */ && ts.nodeIsMissing(ts.getContainingFunction(node).body)) {
                error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
                return;
            }
            // For a binding pattern, validate the initializer and exit
            if (ts.isBindingPattern(node.name)) {
                if (node.initializer) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
                    checkParameterInitializer(node);
                }
                return;
            }
            var symbol = getSymbolOfNode(node);
            var type = getTypeOfVariableOrParameterOrProperty(symbol);
            if (node === symbol.valueDeclaration) {
                // Node is the primary declaration of the symbol, just validate the initializer
                if (node.initializer) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined);
                    checkParameterInitializer(node);
                }
            }
            else {
                // Node is a secondary declaration, check that type is identical to primary declaration and check that
                // initializer is consistent with type associated with the node
                var declarationType = getWidenedTypeForVariableLikeDeclaration(node);
                if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
                    error(node.name, ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, ts.declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
                }
                if (node.initializer) {
                    checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined);
                }
            }
            if (node.kind !== 141 /* PropertyDeclaration */ && node.kind !== 140 /* PropertySignature */) {
                // We know we don't have a binding pattern or computed name here
                checkExportsOnMergedDeclarations(node);
                if (node.kind === 211 /* VariableDeclaration */ || node.kind === 163 /* BindingElement */) {
                    checkVarDeclaredNamesNotShadowed(node);
                }
                checkCollisionWithCapturedSuperVariable(node, node.name);
                checkCollisionWithCapturedThisVariable(node, node.name);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            }
        }

Check variable, parameter, or property declaration

Check variable parameter or property declaration


function checkElementTypeOfIterable(iterable, errorNode) {
            var elementType = getElementTypeOfIterable(iterable, errorNode);
            // Now even though we have extracted the iteratedType, we will have to validate that the type
            // passed in is actually an Iterable.
            if (errorNode && elementType) {
                checkTypeAssignableTo(iterable, createIterableType(elementType), errorNode);
            }
            return elementType || anyType;
        }

function checkElementTypeOfIterable ( iterable , errorNode ) { var elementType = getElementTypeOfIterable ( iterable , errorNode ) ; if ( errorNode && elementType ) { checkTypeAssignableTo ( iterable , createIterableType ( elementType ) , errorNode ) ; } return elementType || anyType ; }

When errorNode is undefined, it means we should not report any errors.

When errorNode is undefined it means we should not report any errors .