(reference, declaredType, initialType, flowContainer, flowNode)
| 70299 | return false; |
| 70300 | } |
| 70301 | function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, flowNode) { |
| 70302 | if (initialType === void 0) { initialType = declaredType; } |
| 70303 | if (flowNode === void 0) { flowNode = reference.flowNode; } |
| 70304 | var key; |
| 70305 | var isKeySet = false; |
| 70306 | var flowDepth = 0; |
| 70307 | if (flowAnalysisDisabled) { |
| 70308 | return errorType; |
| 70309 | } |
| 70310 | if (!flowNode) { |
| 70311 | return declaredType; |
| 70312 | } |
| 70313 | flowInvocationCount++; |
| 70314 | var sharedFlowStart = sharedFlowCount; |
| 70315 | var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(flowNode)); |
| 70316 | sharedFlowCount = sharedFlowStart; |
| 70317 | // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation, |
| 70318 | // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations |
| 70319 | // on empty arrays are possible without implicit any errors and new element types can be inferred without |
| 70320 | // type mismatch errors. |
| 70321 | var resultType = ts.getObjectFlags(evolvedType) & 256 /* ObjectFlags.EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); |
| 70322 | if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === 230 /* SyntaxKind.NonNullExpression */ && !(resultType.flags & 131072 /* TypeFlags.Never */) && getTypeWithFacts(resultType, 2097152 /* TypeFacts.NEUndefinedOrNull */).flags & 131072 /* TypeFlags.Never */) { |
| 70323 | return declaredType; |
| 70324 | } |
| 70325 | // The non-null unknown type should never escape control flow analysis. |
| 70326 | return resultType === nonNullUnknownType ? unknownType : resultType; |
| 70327 | function getOrSetCacheKey() { |
| 70328 | if (isKeySet) { |
| 70329 | return key; |
| 70330 | } |
| 70331 | isKeySet = true; |
| 70332 | return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer); |
| 70333 | } |
| 70334 | function getTypeAtFlowNode(flow) { |
| 70335 | if (flowDepth === 2000) { |
| 70336 | // We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error |
| 70337 | // and disable further control flow analysis in the containing function or module body. |
| 70338 | ts.tracing === null || ts.tracing === void 0 ? void 0 : ts.tracing.instant("checkTypes" /* tracing.Phase.CheckTypes */, "getTypeAtFlowNode_DepthLimit", { flowId: flow.id }); |
| 70339 | flowAnalysisDisabled = true; |
| 70340 | reportFlowControlError(reference); |
| 70341 | return errorType; |
| 70342 | } |
| 70343 | flowDepth++; |
| 70344 | var sharedFlow; |
| 70345 | while (true) { |
| 70346 | var flags = flow.flags; |
| 70347 | if (flags & 4096 /* FlowFlags.Shared */) { |
| 70348 | // We cache results of flow type resolution for shared nodes that were previously visited in |
| 70349 | // the same getFlowTypeOfReference invocation. A node is considered shared when it is the |
| 70350 | // antecedent of more than one node. |
| 70351 | for (var i = sharedFlowStart; i < sharedFlowCount; i++) { |
| 70352 | if (sharedFlowNodes[i] === flow) { |
| 70353 | flowDepth--; |
| 70354 | return sharedFlowTypes[i]; |
| 70355 | } |
| 70356 | } |
| 70357 | sharedFlow = flow; |
| 70358 | } |
no test coverage detected
searching dependent graphs…