(type, operator, identifier, assumeTrue)
| 71199 | isMatchingReference(reference, expr.expression); |
| 71200 | } |
| 71201 | function narrowTypeByConstructor(type, operator, identifier, assumeTrue) { |
| 71202 | // Do not narrow when checking inequality. |
| 71203 | if (assumeTrue ? (operator !== 34 /* SyntaxKind.EqualsEqualsToken */ && operator !== 36 /* SyntaxKind.EqualsEqualsEqualsToken */) : (operator !== 35 /* SyntaxKind.ExclamationEqualsToken */ && operator !== 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { |
| 71204 | return type; |
| 71205 | } |
| 71206 | // Get the type of the constructor identifier expression, if it is not a function then do not narrow. |
| 71207 | var identifierType = getTypeOfExpression(identifier); |
| 71208 | if (!isFunctionType(identifierType) && !isConstructorType(identifierType)) { |
| 71209 | return type; |
| 71210 | } |
| 71211 | // Get the prototype property of the type identifier so we can find out its type. |
| 71212 | var prototypeProperty = getPropertyOfType(identifierType, "prototype"); |
| 71213 | if (!prototypeProperty) { |
| 71214 | return type; |
| 71215 | } |
| 71216 | // Get the type of the prototype, if it is undefined, or the global `Object` or `Function` types then do not narrow. |
| 71217 | var prototypeType = getTypeOfSymbol(prototypeProperty); |
| 71218 | var candidate = !isTypeAny(prototypeType) ? prototypeType : undefined; |
| 71219 | if (!candidate || candidate === globalObjectType || candidate === globalFunctionType) { |
| 71220 | return type; |
| 71221 | } |
| 71222 | // If the type that is being narrowed is `any` then just return the `candidate` type since every type is a subtype of `any`. |
| 71223 | if (isTypeAny(type)) { |
| 71224 | return candidate; |
| 71225 | } |
| 71226 | // Filter out types that are not considered to be "constructed by" the `candidate` type. |
| 71227 | return filterType(type, function (t) { return isConstructedBy(t, candidate); }); |
| 71228 | function isConstructedBy(source, target) { |
| 71229 | // If either the source or target type are a class type then we need to check that they are the same exact type. |
| 71230 | // This is because you may have a class `A` that defines some set of properties, and another class `B` |
| 71231 | // that defines the same set of properties as class `A`, in that case they are structurally the same |
| 71232 | // type, but when you do something like `instanceOfA.constructor === B` it will return false. |
| 71233 | if (source.flags & 524288 /* TypeFlags.Object */ && ts.getObjectFlags(source) & 1 /* ObjectFlags.Class */ || |
| 71234 | target.flags & 524288 /* TypeFlags.Object */ && ts.getObjectFlags(target) & 1 /* ObjectFlags.Class */) { |
| 71235 | return source.symbol === target.symbol; |
| 71236 | } |
| 71237 | // For all other types just check that the `source` type is a subtype of the `target` type. |
| 71238 | return isTypeSubtypeOf(source, target); |
| 71239 | } |
| 71240 | } |
| 71241 | function narrowTypeByInstanceof(type, expr, assumeTrue) { |
| 71242 | var left = getReferenceCandidate(expr.left); |
| 71243 | if (!isMatchingReference(reference, left)) { |
no test coverage detected
searching dependent graphs…