diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 26aaa713ff9d2..d63d9760172a0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -429,6 +429,7 @@ import { InferenceInfo, InferencePriority, InferTypeNode, + InstanceofExpression, InstantiableType, InstantiationExpressionType, InterfaceDeclaration, @@ -566,6 +567,7 @@ import { isInJSDoc, isInJSFile, isInJsonFile, + isInstanceOfExpression, isInterfaceDeclaration, isInternalModuleImportEqualsDeclaration, isInTopLevelContext, @@ -690,6 +692,7 @@ import { isRestParameter, isRestTypeNode, isRightSideOfAccessExpression, + isRightSideOfInstanceofExpression, isRightSideOfQualifiedNameOrPropertyAccess, isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName, isSameEntityName, @@ -811,7 +814,6 @@ import { LateBoundDeclaration, LateBoundName, LateVisibilityPaintedStatement, - LeftHandSideExpression, length, LiteralExpression, LiteralType, @@ -26917,7 +26919,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function getEffectsSignature(node: CallExpression) { + function getEffectsSignature(node: CallExpression | InstanceofExpression) { const links = getNodeLinks(node); let signature = links.effectsSignature; if (signature === undefined) { @@ -26926,7 +26928,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // circularities in control flow analysis, we use getTypeOfDottedName when resolving the call // target expression of an assertion. let funcType: Type | undefined; - if (node.parent.kind === SyntaxKind.ExpressionStatement) { + if (isBinaryExpression(node)) { + const rightType = checkNonNullExpression(node.right); + funcType = getSymbolHasInstanceMethodOfObjectType(rightType); + } + else if (node.parent.kind === SyntaxKind.ExpressionStatement) { funcType = getTypeOfDottedName(node.expression, /*diagnostic*/ undefined); } else if (node.expression.kind !== SyntaxKind.SuperKeyword) { @@ -27792,7 +27798,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } break; case SyntaxKind.InstanceOfKeyword: - return narrowTypeByInstanceof(type, expr, assumeTrue); + return narrowTypeByInstanceof(type, expr as InstanceofExpression, assumeTrue); case SyntaxKind.InKeyword: if (isPrivateIdentifier(expr.left)) { return narrowTypeByPrivateIdentifierInInExpression(type, expr, assumeTrue); @@ -28088,7 +28094,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { + function narrowTypeByInstanceof(type: Type, expr: InstanceofExpression, assumeTrue: boolean): Type { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) { @@ -28096,7 +28102,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return type; } - const rightType = getTypeOfExpression(expr.right); + const right = expr.right; + const rightType = getTypeOfExpression(right); + if (!isTypeDerivedFrom(rightType, globalObjectType)) { + return type; + } + + // if the right-hand side has an object type with a custom `[Symbol.hasInstance]` method, and that method + // has a type predicate, use the type predicate to perform narrowing. This allows normal `object` types to + // participate in `instanceof`, as per Step 2 of https://tc39.es/ecma262/#sec-instanceofoperator. + const signature = getEffectsSignature(expr); + const predicate = signature && getTypePredicateOfSignature(signature); + if (predicate && predicate.kind === TypePredicateKind.Identifier && predicate.parameterIndex === 0) { + return getNarrowedType(type, predicate.type, assumeTrue, /*checkDerived*/ true); + } if (!isTypeDerivedFrom(rightType, globalFunctionType)) { return type; } @@ -32955,8 +32974,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (isJsxOpeningLikeElement(node)) { checkExpression(node.attributes); } - else if (node.kind !== SyntaxKind.Decorator) { - forEach((node as CallExpression).arguments, argument => { + else if (isBinaryExpression(node)) { + checkExpression(node.left); + } + else if (isCallOrNewExpression(node)) { + forEach(node.arguments, argument => { checkExpression(argument); }); } @@ -33064,6 +33086,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (node.kind === SyntaxKind.Decorator) { argCount = getDecoratorArgumentCount(node, signature); } + else if (node.kind === SyntaxKind.BinaryExpression) { + argCount = 1; + } else if (isJsxOpeningLikeElement(node)) { callIsIncomplete = node.attributes.end === node.end; if (callIsIncomplete) { @@ -33172,12 +33197,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getInferredTypes(context); } - function getThisArgumentType(thisArgumentNode: LeftHandSideExpression | undefined) { + function getThisArgumentType(thisArgumentNode: Expression | undefined) { if (!thisArgumentNode) { return voidType; } const thisArgumentType = checkExpression(thisArgumentNode); - return isOptionalChainRoot(thisArgumentNode.parent) ? getNonNullableType(thisArgumentType) : + return isRightSideOfInstanceofExpression(thisArgumentNode) ? thisArgumentType : + isOptionalChainRoot(thisArgumentNode.parent) ? getNonNullableType(thisArgumentType) : isOptionalChain(thisArgumentNode.parent) ? removeOptionalTypeMarker(thisArgumentType) : thisArgumentType; } @@ -33191,7 +33217,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // example, given a 'function wrap(cb: (x: T) => U): (x: T) => U' and a call expression // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the // return type of 'wrap'. - if (node.kind !== SyntaxKind.Decorator) { + if (node.kind !== SyntaxKind.Decorator && node.kind !== SyntaxKind.BinaryExpression) { const skipBindingPatterns = every(signature.typeParameters, p => !!getDefaultFromTypeParameter(p)); const contextualType = getContextualType(node, skipBindingPatterns ? ContextFlags.SkipBindingPatterns : ContextFlags.None); if (contextualType) { @@ -33569,7 +33595,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { /** * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise. */ - function getThisArgumentOfCall(node: CallLikeExpression): LeftHandSideExpression | undefined { + function getThisArgumentOfCall(node: CallLikeExpression): Expression | undefined { + if (node.kind === SyntaxKind.BinaryExpression) { + return node.right; + } + const expression = node.kind === SyntaxKind.CallExpression ? node.expression : node.kind === SyntaxKind.TaggedTemplateExpression ? node.tag : node.kind === SyntaxKind.Decorator && !legacyDecorators ? node.expression : @@ -33606,6 +33636,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.kind === SyntaxKind.Decorator) { return getEffectiveDecoratorArguments(node); } + if (node.kind === SyntaxKind.BinaryExpression) { + return [node.left]; + } if (isJsxOpeningLikeElement(node)) { return node.attributes.properties.length > 0 || (isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : emptyArray; } @@ -33866,11 +33899,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); + const isInstanceof = node.kind === SyntaxKind.BinaryExpression; const reportErrors = !isInferencePartiallyBlocked && !candidatesOutArray; let typeArguments: NodeArray | undefined; - if (!isDecorator && !isSuperCall(node)) { + if (!isDecorator && !isInstanceof && !isSuperCall(node)) { typeArguments = (node as CallExpression).typeArguments; // We already perform checking on the type arguments on the class declaration itself. @@ -33967,6 +34001,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // If candidate is undefined, it means that no candidates had a suitable arity. In that case, // skip the checkApplicableSignature check. if (reportErrors) { + // If the call expression is a synthetic call to a `[Symbol.hasInstance]` method then we will produce a head + // message when reporting diagnostics that explains how we got to `right[Symbol.hasInstance](left)` from + // `left instanceof right`, as it pertains to "Argument" related messages reported for the call. + if (!headMessage && isInstanceof) { + headMessage = Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_assignable_to_the_first_argument_of_the_right_hand_side_s_Symbol_hasInstance_method; + } if (candidatesForArgumentError) { if (candidatesForArgumentError.length === 1 || candidatesForArgumentError.length > 3) { const last = candidatesForArgumentError[candidatesForArgumentError.length - 1]; @@ -34838,6 +34878,39 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveCall(node, signatures, candidatesOutArray, checkMode, SignatureFlags.None); } + function resolveInstanceofExpression(node: InstanceofExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode): Signature { + // if rightType is an object type with a custom `[Symbol.hasInstance]` method, then it is potentially + // valid on the right-hand side of the `instanceof` operator. This allows normal `object` types to + // participate in `instanceof`, as per Step 2 of https://tc39.es/ecma262/#sec-instanceofoperator. + const rightType = checkExpression(node.right); + if (!isTypeAny(rightType)) { + const hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(rightType); + if (hasInstanceMethodType) { + const apparentType = getApparentType(hasInstanceMethodType); + if (isErrorType(apparentType)) { + return resolveErrorCall(node); + } + + const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); + const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct); + if (isUntypedFunctionCall(hasInstanceMethodType, apparentType, callSignatures.length, constructSignatures.length)) { + return resolveUntypedCall(node); + } + + if (callSignatures.length) { + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None); + } + } + // NOTE: do not raise error if right is unknown as related error was already reported + else if (!(typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { + error(node.right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_a_class_function_or_other_type_assignable_to_the_Function_interface_type_or_an_object_type_with_a_Symbol_hasInstance_method); + return resolveErrorCall(node); + } + } + // fall back to a default signature + return anySignature; + } + /** * Sometimes, we have a decorator that could accept zero arguments, * but is receiving too many arguments as part of the decorator invocation. @@ -34863,6 +34936,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode); + case SyntaxKind.BinaryExpression: + return resolveInstanceofExpression(node, candidatesOutArray, checkMode); } Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable."); } @@ -37187,10 +37262,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return (symbol.flags & SymbolFlags.ConstEnum) !== 0; } - function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type { + /** + * Get the type of the `[Symbol.hasInstance]` method of an object type. + */ + function getSymbolHasInstanceMethodOfObjectType(type: Type) { + const hasInstancePropertyName = getPropertyNameForKnownSymbolName("hasInstance"); + const hasInstanceProperty = getPropertyOfObjectType(type, hasInstancePropertyName); + if (hasInstanceProperty) { + const hasInstancePropertyType = getTypeOfSymbol(hasInstanceProperty); + if (hasInstancePropertyType && getSignaturesOfType(hasInstancePropertyType, SignatureKind.Call).length !== 0) { + return hasInstancePropertyType; + } + } + } + + function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type, checkMode?: CheckMode): Type { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } + // TypeScript 1.0 spec (April 2014): 4.15.4 // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type, // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature. @@ -37202,10 +37292,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ) { error(left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } - // NOTE: do not raise error if right is unknown as related error was already reported - if (!(isTypeAny(rightType) || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { - error(right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type); + + Debug.assert(isInstanceOfExpression(left.parent)); + const signature = getResolvedSignature(left.parent, /*candidatesOutArray*/ undefined, checkMode); + if (signature === resolvingSignature) { + // CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that + // returns a function type. We defer checking and return silentNeverType. + return silentNeverType; } + + // If rightType has a `[Symbol.hasInstance]` method that is not `(value: unknown) => boolean`, we + // must check the expression as if it were a call to `right[Symbol.hasInstance](left)`. The call to + // `getResolvedSignature`, below, will check that leftType is assignable to the type of the first + // parameter. + const returnType = getReturnTypeOfSignature(signature); + + // We also verify that the return type of the `[Symbol.hasInstance]` method is assignable to + // `boolean`. According to the spec, the runtime will actually perform `ToBoolean` on the result, + // but this is more type-safe. + checkTypeAssignableTo(returnType, booleanType, right, Diagnostics.An_object_s_Symbol_hasInstance_method_must_return_a_boolean_value_for_it_to_be_used_on_the_right_hand_side_of_an_instanceof_expression); + return booleanType; } @@ -37839,7 +37945,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return booleanType; case SyntaxKind.InstanceOfKeyword: - return checkInstanceOfExpression(left, right, leftType, rightType); + return checkInstanceOfExpression(left, right, leftType, rightType, checkMode); case SyntaxKind.InKeyword: return checkInExpression(left, right, leftType, rightType); case SyntaxKind.AmpersandAmpersandToken: @@ -46024,6 +46130,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.AsExpression: case SyntaxKind.ParenthesizedExpression: checkAssertionDeferred(node as AssertionExpression | JSDocTypeAssertion); + break; + case SyntaxKind.BinaryExpression: + if (isInstanceOfExpression(node)) { + resolveUntypedCall(node); + } + break; } currentNode = saveCurrentNode; tracing?.pop(); @@ -46762,6 +46874,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.ImportKeyword: case SyntaxKind.NewKeyword: return isMetaProperty(node.parent) ? checkMetaPropertyKeyword(node.parent).symbol : undefined; + case SyntaxKind.InstanceOfKeyword: + if (isBinaryExpression(node.parent)) { + const type = getTypeOfExpression(node.parent.right); + const hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(type); + return hasInstanceMethodType?.symbol ?? type.symbol; + } + return undefined; case SyntaxKind.MetaProperty: return checkExpression(node as Expression).symbol; case SyntaxKind.JsxNamespacedName: diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e8709e6ae3068..31955155b0fc9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1920,7 +1920,7 @@ "category": "Error", "code": 2358 }, - "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type.": { + "The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method.": { "category": "Error", "code": 2359 }, @@ -3691,6 +3691,14 @@ "category": "Error", "code": 2859 }, + "The left-hand side of an 'instanceof' expression must be assignable to the first argument of the right-hand side's '[Symbol.hasInstance]' method.": { + "category": "Error", + "code": 2860 + }, + "An object's '[Symbol.hasInstance]' method must return a boolean value for it to be used on the right-hand side of an 'instanceof' expression.": { + "category": "Error", + "code": 2861 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6679431cc39f9..d4860ec7621a8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3053,12 +3053,17 @@ export interface TaggedTemplateExpression extends MemberExpression { /** @internal */ questionDotToken?: QuestionDotToken; // NOTE: Invalid syntax, only used to report a grammar error. } +export interface InstanceofExpression extends BinaryExpression { + readonly operatorToken: Token; +} + export type CallLikeExpression = | CallExpression | NewExpression | TaggedTemplateExpression | Decorator - | JsxOpeningLikeElement; + | JsxOpeningLikeElement + | InstanceofExpression; export interface AsExpression extends Expression { readonly kind: SyntaxKind.AsExpression; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b696ec28a0cc5..9d5e2de2bed23 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -231,6 +231,7 @@ import { IndexSignatureDeclaration, InitializedVariableDeclaration, insertSorted, + InstanceofExpression, InterfaceDeclaration, InternalEmitFlags, isAccessor, @@ -3120,6 +3121,8 @@ export function getInvokedExpression(node: CallLikeExpression): Expression | Jsx case SyntaxKind.JsxOpeningElement: case SyntaxKind.JsxSelfClosingElement: return node.tagName; + case SyntaxKind.BinaryExpression: + return node.right; default: return node.expression; } @@ -7235,6 +7238,15 @@ export function isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName(node || isPropertyAccessExpression(node.parent) && node.parent.name === node || isJSDocMemberName(node.parent) && node.parent.right === node; } +/** @internal */ +export function isInstanceOfExpression(node: Node): node is InstanceofExpression { + return isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.InstanceOfKeyword; +} + +/** @internal */ +export function isRightSideOfInstanceofExpression(node: Node) { + return isInstanceOfExpression(node.parent) && node === node.parent.right; +} /** @internal */ export function isEmptyObjectLiteral(expression: Node): boolean { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 34d2f5cfbc90d..8f70f7cfa107a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5646,7 +5646,10 @@ declare namespace ts { readonly typeArguments?: NodeArray; readonly template: TemplateLiteral; } - type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; + interface InstanceofExpression extends BinaryExpression { + readonly operatorToken: Token; + } + type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement | InstanceofExpression; interface AsExpression extends Expression { readonly kind: SyntaxKind.AsExpression; readonly expression: Expression; diff --git a/tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.symbols b/tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.symbols new file mode 100644 index 0000000000000..4c19470419e35 --- /dev/null +++ b/tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.symbols @@ -0,0 +1,293 @@ +//// [tests/cases/compiler/controlFlowInstanceofWithSymbolHasInstance.ts] //// + +=== controlFlowInstanceofWithSymbolHasInstance.ts === +interface PromiseConstructor { +>PromiseConstructor : Symbol(PromiseConstructor, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 0, 0)) + + [Symbol.hasInstance](value: any): value is Promise; +>[Symbol.hasInstance] : Symbol(PromiseConstructor[Symbol.hasInstance], Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 0, 30)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 1, 25)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 1, 25)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +} + +interface SetConstructor { +>SetConstructor : Symbol(SetConstructor, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 2, 1)) + + [Symbol.hasInstance](value: any): value is Set; +>[Symbol.hasInstance] : Symbol(SetConstructor[Symbol.hasInstance], Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 4, 26)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 5, 25)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 5, 25)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +} + +function f1(s: Set | Set) { +>f1 : Symbol(f1, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 6, 1)) +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s = new Set(); +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) + + if (s instanceof Set) { +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) + } + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) + + s.add(42); +>s.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 8, 12)) +>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) +} + +function f2(s: Set | Set) { +>f2 : Symbol(f2, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 16, 1)) +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s = new Set(); +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) + + if (s instanceof Promise) { +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set & Promise +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) + } + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) + + s.add(42); +>s.add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 18, 12)) +>add : Symbol(Set.add, Decl(lib.es2015.collection.d.ts, --, --)) +} + +function f3(s: Set | Set) { +>f3 : Symbol(f3, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 26, 1)) +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 28, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set | Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 28, 12)) + + if (s instanceof Set) { +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 28, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set | Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 28, 12)) + } + else { + s; // never +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 28, 12)) + } +} + +function f4(s: Set | Set) { +>f4 : Symbol(f4, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 36, 1)) +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 38, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s = new Set(); +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 38, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 38, 12)) + + if (s instanceof Set) { +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 38, 12)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + s; // Set +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 38, 12)) + } + else { + s; // never +>s : Symbol(s, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 38, 12)) + } +} + +// More tests + +class A { +>A : Symbol(A, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 47, 1)) + + a: string; +>a : Symbol(A.a, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 51, 9)) + + static [Symbol.hasInstance](this: T, value: unknown): value is ( +>[Symbol.hasInstance] : Symbol(A[Symbol.hasInstance], Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 52, 14)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>T : Symbol(T, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 32)) +>this : Symbol(this, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 35)) +>T : Symbol(T, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 32)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 43)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 43)) + + T extends (abstract new (...args: any) => infer U) ? U : +>T : Symbol(T, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 32)) +>args : Symbol(args, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 54, 33)) +>U : Symbol(U, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 54, 55)) +>U : Symbol(U, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 54, 55)) + + never + ) { + return Function.prototype[Symbol.hasInstance].call(this, value); +>Function.prototype[Symbol.hasInstance].call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>Function.prototype : Symbol(FunctionConstructor.prototype, Decl(lib.es5.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>prototype : Symbol(FunctionConstructor.prototype, Decl(lib.es5.d.ts, --, --)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>this : Symbol(this, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 35)) +>value : Symbol(value, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 53, 43)) + } +} +class B extends A { b: string } +>B : Symbol(B, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 59, 1)) +>A : Symbol(A, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 47, 1)) +>b : Symbol(B.b, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 60, 19)) + +class C extends A { c: string } +>C : Symbol(C, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 60, 31)) +>A : Symbol(A, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 47, 1)) +>c : Symbol(C.c, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 61, 19)) + +function foo(x: A | undefined) { +>foo : Symbol(foo, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 61, 31)) +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>A : Symbol(A, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 47, 1)) + + x; // A | undefined +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + + if (x instanceof B || x instanceof C) { +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>B : Symbol(B, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 59, 1)) +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>C : Symbol(C, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 60, 31)) + + x; // B | C +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + } + x; // A | undefined +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + + if (x instanceof B && x instanceof C) { +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>B : Symbol(B, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 59, 1)) +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>C : Symbol(C, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 60, 31)) + + x; // B & C +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + } + x; // A | undefined +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + + if (!x) { +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + + return; + } + x; // A +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + + if (x instanceof B) { +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>B : Symbol(B, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 59, 1)) + + x; // B +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + + if (x instanceof C) { +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +>C : Symbol(C, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 60, 31)) + + x; // B & C +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + } + else { + x; // B +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + } + x; // B +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + } + else { + x; // A +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) + } + x; // A +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 63, 13)) +} + +// X is neither assignable to Y nor a subtype of Y +// Y is assignable to X, but not a subtype of X + +interface X { +>X : Symbol(X, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 91, 1)) + + x?: string; +>x : Symbol(X.x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 96, 13)) +} + +class Y { +>Y : Symbol(Y, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 98, 1)) + + y: string; +>y : Symbol(Y.y, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 100, 9)) +} + +function goo(x: X) { +>goo : Symbol(goo, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 102, 1)) +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 104, 13)) +>X : Symbol(X, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 91, 1)) + + x; +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 104, 13)) + + if (x instanceof Y) { +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 104, 13)) +>Y : Symbol(Y, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 98, 1)) + + x.y; +>x.y : Symbol(Y.y, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 100, 9)) +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 104, 13)) +>y : Symbol(Y.y, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 100, 9)) + } + x; +>x : Symbol(x, Decl(controlFlowInstanceofWithSymbolHasInstance.ts, 104, 13)) +} + + diff --git a/tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.types b/tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.types new file mode 100644 index 0000000000000..03bc83b4a49d5 --- /dev/null +++ b/tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.types @@ -0,0 +1,293 @@ +//// [tests/cases/compiler/controlFlowInstanceofWithSymbolHasInstance.ts] //// + +=== controlFlowInstanceofWithSymbolHasInstance.ts === +interface PromiseConstructor { + [Symbol.hasInstance](value: any): value is Promise; +>[Symbol.hasInstance] : (value: any) => value is Promise +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : any +} + +interface SetConstructor { + [Symbol.hasInstance](value: any): value is Set; +>[Symbol.hasInstance] : (value: any) => value is Set +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : any +} + +function f1(s: Set | Set) { +>f1 : (s: Set | Set) => void +>s : Set | Set + + s = new Set(); +>s = new Set() : Set +>s : Set | Set +>new Set() : Set +>Set : SetConstructor + + s; // Set +>s : Set + + if (s instanceof Set) { +>s instanceof Set : boolean +>s : Set +>Set : SetConstructor + + s; // Set +>s : Set + } + s; // Set +>s : Set + + s.add(42); +>s.add(42) : Set +>s.add : (value: number) => Set +>s : Set +>add : (value: number) => Set +>42 : 42 +} + +function f2(s: Set | Set) { +>f2 : (s: Set | Set) => void +>s : Set | Set + + s = new Set(); +>s = new Set() : Set +>s : Set | Set +>new Set() : Set +>Set : SetConstructor + + s; // Set +>s : Set + + if (s instanceof Promise) { +>s instanceof Promise : boolean +>s : Set +>Promise : PromiseConstructor + + s; // Set & Promise +>s : Set & Promise + } + s; // Set +>s : Set + + s.add(42); +>s.add(42) : Set +>s.add : (value: number) => Set +>s : Set +>add : (value: number) => Set +>42 : 42 +} + +function f3(s: Set | Set) { +>f3 : (s: Set | Set) => void +>s : Set | Set + + s; // Set | Set +>s : Set | Set + + if (s instanceof Set) { +>s instanceof Set : boolean +>s : Set | Set +>Set : SetConstructor + + s; // Set | Set +>s : Set | Set + } + else { + s; // never +>s : never + } +} + +function f4(s: Set | Set) { +>f4 : (s: Set | Set) => void +>s : Set | Set + + s = new Set(); +>s = new Set() : Set +>s : Set | Set +>new Set() : Set +>Set : SetConstructor + + s; // Set +>s : Set + + if (s instanceof Set) { +>s instanceof Set : boolean +>s : Set +>Set : SetConstructor + + s; // Set +>s : Set + } + else { + s; // never +>s : never + } +} + +// More tests + +class A { +>A : A + + a: string; +>a : string + + static [Symbol.hasInstance](this: T, value: unknown): value is ( +>[Symbol.hasInstance] : (this: T, value: unknown) => value is T extends abstract new (...args: any) => infer U ? U : never +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>this : T +>value : unknown + + T extends (abstract new (...args: any) => infer U) ? U : +>args : any + + never + ) { + return Function.prototype[Symbol.hasInstance].call(this, value); +>Function.prototype[Symbol.hasInstance].call(this, value) : any +>Function.prototype[Symbol.hasInstance].call : (this: Function, thisArg: any, ...argArray: any[]) => any +>Function.prototype[Symbol.hasInstance] : (value: any) => boolean +>Function.prototype : Function +>Function : FunctionConstructor +>prototype : Function +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>this : T +>value : unknown + } +} +class B extends A { b: string } +>B : B +>A : A +>b : string + +class C extends A { c: string } +>C : C +>A : A +>c : string + +function foo(x: A | undefined) { +>foo : (x: A | undefined) => void +>x : A | undefined + + x; // A | undefined +>x : A | undefined + + if (x instanceof B || x instanceof C) { +>x instanceof B || x instanceof C : boolean +>x instanceof B : boolean +>x : A | undefined +>B : typeof B +>x instanceof C : boolean +>x : A | undefined +>C : typeof C + + x; // B | C +>x : B | C + } + x; // A | undefined +>x : A | undefined + + if (x instanceof B && x instanceof C) { +>x instanceof B && x instanceof C : boolean +>x instanceof B : boolean +>x : A | undefined +>B : typeof B +>x instanceof C : boolean +>x : B +>C : typeof C + + x; // B & C +>x : B & C + } + x; // A | undefined +>x : A | undefined + + if (!x) { +>!x : boolean +>x : A | undefined + + return; + } + x; // A +>x : A + + if (x instanceof B) { +>x instanceof B : boolean +>x : A +>B : typeof B + + x; // B +>x : B + + if (x instanceof C) { +>x instanceof C : boolean +>x : B +>C : typeof C + + x; // B & C +>x : B & C + } + else { + x; // B +>x : B + } + x; // B +>x : B + } + else { + x; // A +>x : A + } + x; // A +>x : A +} + +// X is neither assignable to Y nor a subtype of Y +// Y is assignable to X, but not a subtype of X + +interface X { + x?: string; +>x : string | undefined +} + +class Y { +>Y : Y + + y: string; +>y : string +} + +function goo(x: X) { +>goo : (x: X) => void +>x : X + + x; +>x : X + + if (x instanceof Y) { +>x instanceof Y : boolean +>x : X +>Y : typeof Y + + x.y; +>x.y : string +>x : X & Y +>y : string + } + x; +>x : X +} + + diff --git a/tests/baselines/reference/goToDefinitionInstanceof1.baseline.jsonc b/tests/baselines/reference/goToDefinitionInstanceof1.baseline.jsonc new file mode 100644 index 0000000000000..ed0404414b22f --- /dev/null +++ b/tests/baselines/reference/goToDefinitionInstanceof1.baseline.jsonc @@ -0,0 +1,19 @@ +// === goToDefinition === +// === /tests/cases/fourslash/goToDefinitionInstanceof1.ts === +// <|class [|C|] { +// }|> +// declare var obj: any; +// obj /*GOTO DEF*/instanceof C; + + // === Details === + [ + { + "kind": "class", + "name": "C", + "containerName": "", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/goToDefinitionInstanceof2.baseline.jsonc b/tests/baselines/reference/goToDefinitionInstanceof2.baseline.jsonc new file mode 100644 index 0000000000000..30476d0ad6799 --- /dev/null +++ b/tests/baselines/reference/goToDefinitionInstanceof2.baseline.jsonc @@ -0,0 +1,20 @@ +// === goToDefinition === +// === /main.ts === +// class C { +// <|static [|[Symbol.hasInstance]|](value: unknown): boolean { return true; }|> +// } +// declare var obj: any; +// obj /*GOTO DEF*/instanceof C; + + // === Details === + [ + { + "kind": "method", + "name": "[Symbol.hasInstance]", + "containerName": "C", + "isLocal": false, + "isAmbient": false, + "unverified": false, + "failedAliasResolution": false + } + ] \ No newline at end of file diff --git a/tests/baselines/reference/instanceofOperator.errors.txt b/tests/baselines/reference/instanceofOperator.errors.txt index 2fc2fd255fb6f..032389a10bee2 100644 --- a/tests/baselines/reference/instanceofOperator.errors.txt +++ b/tests/baselines/reference/instanceofOperator.errors.txt @@ -1,7 +1,7 @@ instanceofOperator.ts(7,11): error TS2725: Class name cannot be 'Object' when targeting ES5 with module CommonJS. instanceofOperator.ts(12,5): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -instanceofOperator.ts(15,20): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperator.ts(16,23): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +instanceofOperator.ts(15,20): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperator.ts(16,23): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. instanceofOperator.ts(19,5): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. instanceofOperator.ts(21,5): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. @@ -27,10 +27,10 @@ instanceofOperator.ts(21,5): error TS2358: The left-hand side of an 'instanceof' // Error and should be error obj instanceof 4; ~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. Object instanceof obj; ~~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. // Error on left hand side null instanceof null; diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.errors.txt b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.errors.txt index c3479d67288fe..7c27b020db429 100644 --- a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.errors.txt @@ -7,18 +7,18 @@ instanceofOperatorWithInvalidOperands.ts(19,11): error TS2358: The left-hand sid instanceofOperatorWithInvalidOperands.ts(20,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. instanceofOperatorWithInvalidOperands.ts(21,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. instanceofOperatorWithInvalidOperands.ts(22,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -instanceofOperatorWithInvalidOperands.ts(34,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(35,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(36,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(37,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(38,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(39,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(40,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(41,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(42,24): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.ts(43,25): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.ts(34,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(35,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(36,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(37,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(38,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(39,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(40,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(41,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(42,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.ts(43,25): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. instanceofOperatorWithInvalidOperands.ts(46,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -instanceofOperatorWithInvalidOperands.ts(46,25): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.ts(46,25): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. ==== instanceofOperatorWithInvalidOperands.ts (21 errors) ==== @@ -75,38 +75,38 @@ instanceofOperatorWithInvalidOperands.ts(46,25): error TS2359: The right-hand si var rb1 = x instanceof b1; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb2 = x instanceof b2; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb3 = x instanceof b3; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb4 = x instanceof b4; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb5 = x instanceof 0; ~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb6 = x instanceof true; ~~~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb7 = x instanceof ''; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb8 = x instanceof o1; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb9 = x instanceof o2; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. var rb10 = x instanceof o3; ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. // both operands are invalid var rc1 = '' instanceof {}; ~~ !!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. ~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. \ No newline at end of file +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. \ No newline at end of file diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt new file mode 100644 index 0000000000000..f65722f6e3ef3 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt @@ -0,0 +1,132 @@ +instanceofOperatorWithInvalidOperands.es2015.ts(14,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(15,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(16,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(17,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(18,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(19,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(20,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(21,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(22,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(34,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(35,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(36,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(37,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(38,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(39,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(40,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(41,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(42,24): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(43,25): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(46,11): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +instanceofOperatorWithInvalidOperands.es2015.ts(46,25): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +instanceofOperatorWithInvalidOperands.es2015.ts(51,12): error TS2860: The left-hand side of an 'instanceof' expression must be assignable to the first argument of the right-hand side's '[Symbol.hasInstance]' method. + Argument of type '{ y: string; }' is not assignable to parameter of type '{ x: number; }'. + Property 'x' is missing in type '{ y: string; }' but required in type '{ x: number; }'. +instanceofOperatorWithInvalidOperands.es2015.ts(55,25): error TS2861: An object's '[Symbol.hasInstance]' method must return a boolean value for it to be used on the right-hand side of an 'instanceof' expression. + + +==== instanceofOperatorWithInvalidOperands.es2015.ts (23 errors) ==== + class C { + foo() { } + } + + var x: any; + + // invalid left operand + // the left operand is required to be of type Any, an object type, or a type parameter type + var a1: number; + var a2: boolean; + var a3: string; + var a4: void; + + var ra1 = a1 instanceof x; + ~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra2 = a2 instanceof x; + ~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra3 = a3 instanceof x; + ~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra4 = a4 instanceof x; + ~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra5 = 0 instanceof x; + ~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra6 = true instanceof x; + ~~~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra7 = '' instanceof x; + ~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra8 = null instanceof x; + ~~~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + var ra9 = undefined instanceof x; + ~~~~~~~~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + + // invalid right operand + // the right operand to be of type Any or a subtype of the 'Function' interface type + var b1: number; + var b2: boolean; + var b3: string; + var b4: void; + var o1: {}; + var o2: Object; + var o3: C; + + var rb1 = x instanceof b1; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb2 = x instanceof b2; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb3 = x instanceof b3; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb4 = x instanceof b4; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb5 = x instanceof 0; + ~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb6 = x instanceof true; + ~~~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb7 = x instanceof ''; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb8 = x instanceof o1; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb9 = x instanceof o2; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + var rb10 = x instanceof o3; + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + + // both operands are invalid + var rc1 = '' instanceof {}; + ~~ +!!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + ~~ +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. + + // @@hasInstance restricts LHS + var o4: {[Symbol.hasInstance](value: { x: number }): boolean;}; + var o5: { y: string }; + var ra10 = o5 instanceof o4; + ~~ +!!! error TS2860: The left-hand side of an 'instanceof' expression must be assignable to the first argument of the right-hand side's '[Symbol.hasInstance]' method. +!!! error TS2860: Argument of type '{ y: string; }' is not assignable to parameter of type '{ x: number; }'. +!!! error TS2860: Property 'x' is missing in type '{ y: string; }' but required in type '{ x: number; }'. +!!! related TS2728 instanceofOperatorWithInvalidOperands.es2015.ts:49:40: 'x' is declared here. + + // invalid @@hasInstance method return type on RHS + var o6: {[Symbol.hasInstance](value: unknown): number;}; + var rb11 = x instanceof o6; + ~~ +!!! error TS2861: An object's '[Symbol.hasInstance]' method must return a boolean value for it to be used on the right-hand side of an 'instanceof' expression. \ No newline at end of file diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.js b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.js new file mode 100644 index 0000000000000..738afe34a063d --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.js @@ -0,0 +1,107 @@ +//// [tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts] //// + +//// [instanceofOperatorWithInvalidOperands.es2015.ts] +class C { + foo() { } +} + +var x: any; + +// invalid left operand +// the left operand is required to be of type Any, an object type, or a type parameter type +var a1: number; +var a2: boolean; +var a3: string; +var a4: void; + +var ra1 = a1 instanceof x; +var ra2 = a2 instanceof x; +var ra3 = a3 instanceof x; +var ra4 = a4 instanceof x; +var ra5 = 0 instanceof x; +var ra6 = true instanceof x; +var ra7 = '' instanceof x; +var ra8 = null instanceof x; +var ra9 = undefined instanceof x; + +// invalid right operand +// the right operand to be of type Any or a subtype of the 'Function' interface type +var b1: number; +var b2: boolean; +var b3: string; +var b4: void; +var o1: {}; +var o2: Object; +var o3: C; + +var rb1 = x instanceof b1; +var rb2 = x instanceof b2; +var rb3 = x instanceof b3; +var rb4 = x instanceof b4; +var rb5 = x instanceof 0; +var rb6 = x instanceof true; +var rb7 = x instanceof ''; +var rb8 = x instanceof o1; +var rb9 = x instanceof o2; +var rb10 = x instanceof o3; + +// both operands are invalid +var rc1 = '' instanceof {}; + +// @@hasInstance restricts LHS +var o4: {[Symbol.hasInstance](value: { x: number }): boolean;}; +var o5: { y: string }; +var ra10 = o5 instanceof o4; + +// invalid @@hasInstance method return type on RHS +var o6: {[Symbol.hasInstance](value: unknown): number;}; +var rb11 = x instanceof o6; + +//// [instanceofOperatorWithInvalidOperands.es2015.js] +class C { + foo() { } +} +var x; +// invalid left operand +// the left operand is required to be of type Any, an object type, or a type parameter type +var a1; +var a2; +var a3; +var a4; +var ra1 = a1 instanceof x; +var ra2 = a2 instanceof x; +var ra3 = a3 instanceof x; +var ra4 = a4 instanceof x; +var ra5 = 0 instanceof x; +var ra6 = true instanceof x; +var ra7 = '' instanceof x; +var ra8 = null instanceof x; +var ra9 = undefined instanceof x; +// invalid right operand +// the right operand to be of type Any or a subtype of the 'Function' interface type +var b1; +var b2; +var b3; +var b4; +var o1; +var o2; +var o3; +var rb1 = x instanceof b1; +var rb2 = x instanceof b2; +var rb3 = x instanceof b3; +var rb4 = x instanceof b4; +var rb5 = x instanceof 0; +var rb6 = x instanceof true; +var rb7 = x instanceof ''; +var rb8 = x instanceof o1; +var rb9 = x instanceof o2; +var rb10 = x instanceof o3; +// both operands are invalid +var rc1 = '' instanceof {}; +// @@hasInstance restricts LHS +var o4; +var o5; +var ra10 = o5 instanceof o4; +// invalid @@hasInstance method return type on RHS +var o6; +var rb11 = x instanceof o6; diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.symbols b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.symbols new file mode 100644 index 0000000000000..4936b1a4ac7e6 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.symbols @@ -0,0 +1,177 @@ +//// [tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts] //// + +=== instanceofOperatorWithInvalidOperands.es2015.ts === +class C { +>C : Symbol(C, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 0, 0)) + + foo() { } +>foo : Symbol(C.foo, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 0, 9)) +} + +var x: any; +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +// invalid left operand +// the left operand is required to be of type Any, an object type, or a type parameter type +var a1: number; +>a1 : Symbol(a1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 8, 3)) + +var a2: boolean; +>a2 : Symbol(a2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 9, 3)) + +var a3: string; +>a3 : Symbol(a3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 10, 3)) + +var a4: void; +>a4 : Symbol(a4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 11, 3)) + +var ra1 = a1 instanceof x; +>ra1 : Symbol(ra1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 13, 3)) +>a1 : Symbol(a1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 8, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra2 = a2 instanceof x; +>ra2 : Symbol(ra2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 14, 3)) +>a2 : Symbol(a2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 9, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra3 = a3 instanceof x; +>ra3 : Symbol(ra3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 15, 3)) +>a3 : Symbol(a3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 10, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra4 = a4 instanceof x; +>ra4 : Symbol(ra4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 16, 3)) +>a4 : Symbol(a4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 11, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra5 = 0 instanceof x; +>ra5 : Symbol(ra5, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 17, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra6 = true instanceof x; +>ra6 : Symbol(ra6, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 18, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra7 = '' instanceof x; +>ra7 : Symbol(ra7, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 19, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra8 = null instanceof x; +>ra8 : Symbol(ra8, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 20, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var ra9 = undefined instanceof x; +>ra9 : Symbol(ra9, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 21, 3)) +>undefined : Symbol(undefined) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +// invalid right operand +// the right operand to be of type Any or a subtype of the 'Function' interface type +var b1: number; +>b1 : Symbol(b1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 25, 3)) + +var b2: boolean; +>b2 : Symbol(b2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 26, 3)) + +var b3: string; +>b3 : Symbol(b3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 27, 3)) + +var b4: void; +>b4 : Symbol(b4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 28, 3)) + +var o1: {}; +>o1 : Symbol(o1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 29, 3)) + +var o2: Object; +>o2 : Symbol(o2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 30, 3)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +var o3: C; +>o3 : Symbol(o3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 31, 3)) +>C : Symbol(C, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 0, 0)) + +var rb1 = x instanceof b1; +>rb1 : Symbol(rb1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 33, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>b1 : Symbol(b1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 25, 3)) + +var rb2 = x instanceof b2; +>rb2 : Symbol(rb2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 34, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>b2 : Symbol(b2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 26, 3)) + +var rb3 = x instanceof b3; +>rb3 : Symbol(rb3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 35, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>b3 : Symbol(b3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 27, 3)) + +var rb4 = x instanceof b4; +>rb4 : Symbol(rb4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 36, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>b4 : Symbol(b4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 28, 3)) + +var rb5 = x instanceof 0; +>rb5 : Symbol(rb5, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 37, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var rb6 = x instanceof true; +>rb6 : Symbol(rb6, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 38, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var rb7 = x instanceof ''; +>rb7 : Symbol(rb7, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 39, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) + +var rb8 = x instanceof o1; +>rb8 : Symbol(rb8, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 40, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>o1 : Symbol(o1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 29, 3)) + +var rb9 = x instanceof o2; +>rb9 : Symbol(rb9, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 41, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>o2 : Symbol(o2, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 30, 3)) + +var rb10 = x instanceof o3; +>rb10 : Symbol(rb10, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 42, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>o3 : Symbol(o3, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 31, 3)) + +// both operands are invalid +var rc1 = '' instanceof {}; +>rc1 : Symbol(rc1, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 45, 3)) + +// @@hasInstance restricts LHS +var o4: {[Symbol.hasInstance](value: { x: number }): boolean;}; +>o4 : Symbol(o4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 48, 3)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 48, 9)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 48, 30)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 48, 38)) + +var o5: { y: string }; +>o5 : Symbol(o5, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 49, 3)) +>y : Symbol(y, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 49, 9)) + +var ra10 = o5 instanceof o4; +>ra10 : Symbol(ra10, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 50, 3)) +>o5 : Symbol(o5, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 49, 3)) +>o4 : Symbol(o4, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 48, 3)) + +// invalid @@hasInstance method return type on RHS +var o6: {[Symbol.hasInstance](value: unknown): number;}; +>o6 : Symbol(o6, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 53, 3)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 53, 9)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 53, 30)) + +var rb11 = x instanceof o6; +>rb11 : Symbol(rb11, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 54, 3)) +>x : Symbol(x, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 4, 3)) +>o6 : Symbol(o6, Decl(instanceofOperatorWithInvalidOperands.es2015.ts, 53, 3)) + diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.types b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.types new file mode 100644 index 0000000000000..480c5e6f1f182 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.types @@ -0,0 +1,205 @@ +//// [tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts] //// + +=== instanceofOperatorWithInvalidOperands.es2015.ts === +class C { +>C : C + + foo() { } +>foo : () => void +} + +var x: any; +>x : any + +// invalid left operand +// the left operand is required to be of type Any, an object type, or a type parameter type +var a1: number; +>a1 : number + +var a2: boolean; +>a2 : boolean + +var a3: string; +>a3 : string + +var a4: void; +>a4 : void + +var ra1 = a1 instanceof x; +>ra1 : boolean +>a1 instanceof x : boolean +>a1 : number +>x : any + +var ra2 = a2 instanceof x; +>ra2 : boolean +>a2 instanceof x : boolean +>a2 : boolean +>x : any + +var ra3 = a3 instanceof x; +>ra3 : boolean +>a3 instanceof x : boolean +>a3 : string +>x : any + +var ra4 = a4 instanceof x; +>ra4 : boolean +>a4 instanceof x : boolean +>a4 : void +>x : any + +var ra5 = 0 instanceof x; +>ra5 : boolean +>0 instanceof x : boolean +>0 : 0 +>x : any + +var ra6 = true instanceof x; +>ra6 : boolean +>true instanceof x : boolean +>true : true +>x : any + +var ra7 = '' instanceof x; +>ra7 : boolean +>'' instanceof x : boolean +>'' : "" +>x : any + +var ra8 = null instanceof x; +>ra8 : boolean +>null instanceof x : boolean +>x : any + +var ra9 = undefined instanceof x; +>ra9 : boolean +>undefined instanceof x : boolean +>undefined : undefined +>x : any + +// invalid right operand +// the right operand to be of type Any or a subtype of the 'Function' interface type +var b1: number; +>b1 : number + +var b2: boolean; +>b2 : boolean + +var b3: string; +>b3 : string + +var b4: void; +>b4 : void + +var o1: {}; +>o1 : {} + +var o2: Object; +>o2 : Object + +var o3: C; +>o3 : C + +var rb1 = x instanceof b1; +>rb1 : boolean +>x instanceof b1 : boolean +>x : any +>b1 : number + +var rb2 = x instanceof b2; +>rb2 : boolean +>x instanceof b2 : boolean +>x : any +>b2 : boolean + +var rb3 = x instanceof b3; +>rb3 : boolean +>x instanceof b3 : boolean +>x : any +>b3 : string + +var rb4 = x instanceof b4; +>rb4 : boolean +>x instanceof b4 : boolean +>x : any +>b4 : void + +var rb5 = x instanceof 0; +>rb5 : boolean +>x instanceof 0 : boolean +>x : any +>0 : 0 + +var rb6 = x instanceof true; +>rb6 : boolean +>x instanceof true : boolean +>x : any +>true : true + +var rb7 = x instanceof ''; +>rb7 : boolean +>x instanceof '' : boolean +>x : any +>'' : "" + +var rb8 = x instanceof o1; +>rb8 : boolean +>x instanceof o1 : boolean +>x : any +>o1 : {} + +var rb9 = x instanceof o2; +>rb9 : boolean +>x instanceof o2 : boolean +>x : any +>o2 : Object + +var rb10 = x instanceof o3; +>rb10 : boolean +>x instanceof o3 : boolean +>x : any +>o3 : C + +// both operands are invalid +var rc1 = '' instanceof {}; +>rc1 : boolean +>'' instanceof {} : boolean +>'' : "" +>{} : {} + +// @@hasInstance restricts LHS +var o4: {[Symbol.hasInstance](value: { x: number }): boolean;}; +>o4 : { [Symbol.hasInstance](value: { x: number;}): boolean; } +>[Symbol.hasInstance] : (value: { x: number;}) => boolean +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : { x: number; } +>x : number + +var o5: { y: string }; +>o5 : { y: string; } +>y : string + +var ra10 = o5 instanceof o4; +>ra10 : boolean +>o5 instanceof o4 : boolean +>o5 : { y: string; } +>o4 : { [Symbol.hasInstance](value: { x: number; }): boolean; } + +// invalid @@hasInstance method return type on RHS +var o6: {[Symbol.hasInstance](value: unknown): number;}; +>o6 : { [Symbol.hasInstance](value: unknown): number; } +>[Symbol.hasInstance] : (value: unknown) => number +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown + +var rb11 = x instanceof o6; +>rb11 : boolean +>x instanceof o6 : boolean +>x : any +>o6 : { [Symbol.hasInstance](value: unknown): number; } + diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js new file mode 100644 index 0000000000000..0d4984e43e0a0 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js @@ -0,0 +1,184 @@ +//// [tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts] //// + +//// [instanceofOperatorWithRHSHasSymbolHasInstance.ts] +interface Point { x: number, y: number } +interface Point3D { x: number, y: number, z: number } +interface Point3D2 extends Point { z: number } +interface Line { start: Point, end: Point } + +declare var rhs0: { [Symbol.hasInstance](value: unknown): boolean; }; +declare var rhs1: { [Symbol.hasInstance](value: any): boolean; }; +declare var rhs2: { [Symbol.hasInstance](value: any): value is Point; }; +declare var rhs3: { [Symbol.hasInstance](value: Point | Line): value is Point; }; +declare var rhs4: { [Symbol.hasInstance](value: Point | Line): value is Line; }; +declare var rhs5: { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; }; +declare var rhs6: { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; }; + +declare class Rhs7 { static [Symbol.hasInstance](value: unknown): boolean; } +declare class Rhs8 { static [Symbol.hasInstance](value: any): boolean; } +declare class Rhs9 { static [Symbol.hasInstance](value: any): value is Point; } +declare class Rhs10 { static [Symbol.hasInstance](value: Point | Line): value is Point; } +declare class Rhs11 { static [Symbol.hasInstance](value: Point | Line): value is Line; } +declare class Rhs12 { static [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +declare class Rhs13 { static [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } + +declare var lhs0: any; +declare var lhs1: object; +declare var lhs2: Point | Point3D | Line; +declare var lhs3: Point3D | Line; +declare var lhs4: Point | Point3D2 | Line; + +lhs0 instanceof rhs0 && lhs0; +lhs0 instanceof rhs1 && lhs0; +lhs0 instanceof rhs2 && lhs0; +lhs0 instanceof rhs3 && lhs0; +lhs0 instanceof rhs4 && lhs0; +lhs0 instanceof rhs5 && lhs0; +lhs0 instanceof rhs6 && lhs0; +lhs0 instanceof Rhs7 && lhs0; +lhs0 instanceof Rhs8 && lhs0; +lhs0 instanceof Rhs9 && lhs0; +lhs0 instanceof Rhs10 && lhs0; +lhs0 instanceof Rhs11 && lhs0; +lhs0 instanceof Rhs12 && lhs0; +lhs0 instanceof Rhs13 && lhs0; + +lhs1 instanceof rhs0 && lhs1; +lhs1 instanceof rhs1 && lhs1; +lhs1 instanceof rhs2 && lhs1; +lhs1 instanceof Rhs7 && lhs1; +lhs1 instanceof Rhs8 && lhs1; +lhs1 instanceof Rhs9 && lhs1; + +lhs2 instanceof rhs0 && lhs2; +lhs2 instanceof rhs1 && lhs2; +lhs2 instanceof rhs2 && lhs2; +lhs2 instanceof rhs3 && lhs2; +lhs2 instanceof rhs4 && lhs2; +lhs2 instanceof rhs5 && lhs2; +lhs2 instanceof Rhs7 && lhs2; +lhs2 instanceof Rhs8 && lhs2; +lhs2 instanceof Rhs9 && lhs2; +lhs2 instanceof Rhs10 && lhs2; +lhs2 instanceof Rhs11 && lhs2; +lhs2 instanceof Rhs12 && lhs2; + +lhs3 instanceof rhs0 && lhs3; +lhs3 instanceof rhs1 && lhs3; +lhs3 instanceof rhs2 && lhs3; +lhs3 instanceof rhs3 && lhs3; +lhs3 instanceof rhs4 && lhs3; +lhs3 instanceof rhs5 && lhs3; +lhs3 instanceof rhs6 && lhs3; +lhs3 instanceof Rhs7 && lhs3; +lhs3 instanceof Rhs8 && lhs3; +lhs3 instanceof Rhs9 && lhs3; +lhs3 instanceof Rhs10 && lhs3; +lhs3 instanceof Rhs11 && lhs3; +lhs3 instanceof Rhs12 && lhs3; +lhs3 instanceof Rhs13 && lhs3; + +lhs4 instanceof rhs0 && lhs4; +lhs4 instanceof rhs1 && lhs4; +lhs4 instanceof rhs2 && lhs4; +lhs4 instanceof rhs3 && lhs4; +lhs4 instanceof rhs4 && lhs4; +lhs4 instanceof rhs5 && lhs4; +lhs4 instanceof Rhs7 && lhs4; +lhs4 instanceof Rhs8 && lhs4; +lhs4 instanceof Rhs9 && lhs4; +lhs4 instanceof Rhs10 && lhs4; +lhs4 instanceof Rhs11 && lhs4; +lhs4 instanceof Rhs12 && lhs4; + +declare class A { + #x: number; + + // approximation of `getInstanceType` behavior, with one caveat: the checker versions unions the return types of + // all construct signatures, but we have no way of extracting individual construct signatures from a type. + static [Symbol.hasInstance](this: T, value: unknown): value is ( + T extends globalThis.Function ? + T extends { readonly prototype: infer U } ? + boolean extends (U extends never ? true : false) ? // <- tests whether 'U' is 'any' + T extends (abstract new (...args: any) => infer V) ? V : {} : + U : + never : + never + ); +} + +declare class B extends A { #y: number; } + +declare const obj: unknown; +if (obj instanceof A) { + obj; // A +} +if (obj instanceof B) { + obj; // B +} + +//// [instanceofOperatorWithRHSHasSymbolHasInstance.js] +lhs0 instanceof rhs0 && lhs0; +lhs0 instanceof rhs1 && lhs0; +lhs0 instanceof rhs2 && lhs0; +lhs0 instanceof rhs3 && lhs0; +lhs0 instanceof rhs4 && lhs0; +lhs0 instanceof rhs5 && lhs0; +lhs0 instanceof rhs6 && lhs0; +lhs0 instanceof Rhs7 && lhs0; +lhs0 instanceof Rhs8 && lhs0; +lhs0 instanceof Rhs9 && lhs0; +lhs0 instanceof Rhs10 && lhs0; +lhs0 instanceof Rhs11 && lhs0; +lhs0 instanceof Rhs12 && lhs0; +lhs0 instanceof Rhs13 && lhs0; +lhs1 instanceof rhs0 && lhs1; +lhs1 instanceof rhs1 && lhs1; +lhs1 instanceof rhs2 && lhs1; +lhs1 instanceof Rhs7 && lhs1; +lhs1 instanceof Rhs8 && lhs1; +lhs1 instanceof Rhs9 && lhs1; +lhs2 instanceof rhs0 && lhs2; +lhs2 instanceof rhs1 && lhs2; +lhs2 instanceof rhs2 && lhs2; +lhs2 instanceof rhs3 && lhs2; +lhs2 instanceof rhs4 && lhs2; +lhs2 instanceof rhs5 && lhs2; +lhs2 instanceof Rhs7 && lhs2; +lhs2 instanceof Rhs8 && lhs2; +lhs2 instanceof Rhs9 && lhs2; +lhs2 instanceof Rhs10 && lhs2; +lhs2 instanceof Rhs11 && lhs2; +lhs2 instanceof Rhs12 && lhs2; +lhs3 instanceof rhs0 && lhs3; +lhs3 instanceof rhs1 && lhs3; +lhs3 instanceof rhs2 && lhs3; +lhs3 instanceof rhs3 && lhs3; +lhs3 instanceof rhs4 && lhs3; +lhs3 instanceof rhs5 && lhs3; +lhs3 instanceof rhs6 && lhs3; +lhs3 instanceof Rhs7 && lhs3; +lhs3 instanceof Rhs8 && lhs3; +lhs3 instanceof Rhs9 && lhs3; +lhs3 instanceof Rhs10 && lhs3; +lhs3 instanceof Rhs11 && lhs3; +lhs3 instanceof Rhs12 && lhs3; +lhs3 instanceof Rhs13 && lhs3; +lhs4 instanceof rhs0 && lhs4; +lhs4 instanceof rhs1 && lhs4; +lhs4 instanceof rhs2 && lhs4; +lhs4 instanceof rhs3 && lhs4; +lhs4 instanceof rhs4 && lhs4; +lhs4 instanceof rhs5 && lhs4; +lhs4 instanceof Rhs7 && lhs4; +lhs4 instanceof Rhs8 && lhs4; +lhs4 instanceof Rhs9 && lhs4; +lhs4 instanceof Rhs10 && lhs4; +lhs4 instanceof Rhs11 && lhs4; +lhs4 instanceof Rhs12 && lhs4; +if (obj instanceof A) { + obj; // A +} +if (obj instanceof B) { + obj; // B +} diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols new file mode 100644 index 0000000000000..e2d111f8772be --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols @@ -0,0 +1,557 @@ +//// [tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts] //// + +=== instanceofOperatorWithRHSHasSymbolHasInstance.ts === +interface Point { x: number, y: number } +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>x : Symbol(Point.x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 17)) +>y : Symbol(Point.y, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 28)) + +interface Point3D { x: number, y: number, z: number } +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>x : Symbol(Point3D.x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 19)) +>y : Symbol(Point3D.y, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 30)) +>z : Symbol(Point3D.z, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 41)) + +interface Point3D2 extends Point { z: number } +>Point3D2 : Symbol(Point3D2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>z : Symbol(Point3D2.z, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 34)) + +interface Line { start: Point, end: Point } +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>start : Symbol(Line.start, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 3, 16)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>end : Symbol(Line.end, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 3, 30)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +declare var rhs0: { [Symbol.hasInstance](value: unknown): boolean; }; +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 41)) + +declare var rhs1: { [Symbol.hasInstance](value: any): boolean; }; +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 41)) + +declare var rhs2: { [Symbol.hasInstance](value: any): value is Point; }; +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 41)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 41)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +declare var rhs3: { [Symbol.hasInstance](value: Point | Line): value is Point; }; +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 41)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 41)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +declare var rhs4: { [Symbol.hasInstance](value: Point | Line): value is Line; }; +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 41)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 41)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) + +declare var rhs5: { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; }; +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 41)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 41)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) + +declare var rhs6: { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; }; +>rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 19)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 41)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 41)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) + +declare class Rhs7 { static [Symbol.hasInstance](value: unknown): boolean; } +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 85)) +>[Symbol.hasInstance] : Symbol(Rhs7[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 20)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 49)) + +declare class Rhs8 { static [Symbol.hasInstance](value: any): boolean; } +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 76)) +>[Symbol.hasInstance] : Symbol(Rhs8[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 20)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 49)) + +declare class Rhs9 { static [Symbol.hasInstance](value: any): value is Point; } +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 72)) +>[Symbol.hasInstance] : Symbol(Rhs9[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 20)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 49)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 49)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +declare class Rhs10 { static [Symbol.hasInstance](value: Point | Line): value is Point; } +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 79)) +>[Symbol.hasInstance] : Symbol(Rhs10[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 21)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 50)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 50)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +declare class Rhs11 { static [Symbol.hasInstance](value: Point | Line): value is Line; } +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 89)) +>[Symbol.hasInstance] : Symbol(Rhs11[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 21)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 50)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 50)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) + +declare class Rhs12 { static [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 88)) +>[Symbol.hasInstance] : Symbol(Rhs12[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 21)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 50)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 50)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) + +declare class Rhs13 { static [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } +>Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 101)) +>[Symbol.hasInstance] : Symbol(Rhs13[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 19, 21)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 19, 50)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 19, 50)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) + +declare var lhs0: any; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +declare var lhs1: object; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +declare var lhs2: Point | Point3D | Line; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) + +declare var lhs3: Point3D | Line; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) + +declare var lhs4: Point | Point3D2 | Line; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Point3D2 : Symbol(Point3D2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) + +lhs0 instanceof rhs0 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof rhs1 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof rhs2 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof rhs3 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof rhs4 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof rhs5 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof rhs6 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs7 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 85)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs8 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 76)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs9 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 72)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs10 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 79)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs11 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 89)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs12 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 88)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs0 instanceof Rhs13 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 101)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs1 instanceof rhs0 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs1 instanceof rhs1 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs1 instanceof rhs2 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs1 instanceof Rhs7 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 85)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs1 instanceof Rhs8 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 76)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs1 instanceof Rhs9 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 72)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof rhs0 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof rhs1 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof rhs2 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof rhs3 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof rhs4 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof rhs5 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof Rhs7 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 85)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof Rhs8 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 76)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof Rhs9 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 72)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof Rhs10 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 79)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof Rhs11 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 89)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs2 instanceof Rhs12 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 88)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs0 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof rhs1 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof rhs2 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof rhs3 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof rhs4 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof rhs5 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof rhs6 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs7 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 85)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs8 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 76)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs9 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 72)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs10 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 79)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs11 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 89)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs12 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 88)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs3 instanceof Rhs13 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) +>Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 101)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) + +lhs4 instanceof rhs0 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof rhs1 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof rhs2 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof rhs3 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof rhs4 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof rhs5 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof Rhs7 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 11, 85)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof Rhs8 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 76)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof Rhs9 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 72)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof Rhs10 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 79)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof Rhs11 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 89)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +lhs4 instanceof Rhs12 && lhs4; +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 88)) +>lhs4 : Symbol(lhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 25, 11)) + +declare class A { +>A : Symbol(A, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 88, 30)) + + #x: number; +>#x : Symbol(A.#x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 90, 17)) + + // approximation of `getInstanceType` behavior, with one caveat: the checker versions unions the return types of + // all construct signatures, but we have no way of extracting individual construct signatures from a type. + static [Symbol.hasInstance](this: T, value: unknown): value is ( +>[Symbol.hasInstance] : Symbol(A[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 91, 15)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>T : Symbol(T, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 32)) +>this : Symbol(this, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 35)) +>T : Symbol(T, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 32)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 43)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 43)) + + T extends globalThis.Function ? +>T : Symbol(T, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 32)) +>globalThis : Symbol(globalThis) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + T extends { readonly prototype: infer U } ? +>T : Symbol(T, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 32)) +>prototype : Symbol(prototype, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 97, 23)) +>U : Symbol(U, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 97, 49)) + + boolean extends (U extends never ? true : false) ? // <- tests whether 'U' is 'any' +>U : Symbol(U, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 97, 49)) + + T extends (abstract new (...args: any) => infer V) ? V : {} : +>T : Symbol(T, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 95, 32)) +>args : Symbol(args, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 99, 45)) +>V : Symbol(V, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 99, 67)) +>V : Symbol(V, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 99, 67)) + + U : +>U : Symbol(U, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 97, 49)) + + never : + never + ); +} + +declare class B extends A { #y: number; } +>B : Symbol(B, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 104, 1)) +>A : Symbol(A, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 88, 30)) +>#y : Symbol(B.#y, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 106, 27)) + +declare const obj: unknown; +>obj : Symbol(obj, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 108, 13)) + +if (obj instanceof A) { +>obj : Symbol(obj, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 108, 13)) +>A : Symbol(A, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 88, 30)) + + obj; // A +>obj : Symbol(obj, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 108, 13)) +} +if (obj instanceof B) { +>obj : Symbol(obj, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 108, 13)) +>B : Symbol(B, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 104, 1)) + + obj; // B +>obj : Symbol(obj, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 108, 13)) +} diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types new file mode 100644 index 0000000000000..fc8be58916595 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types @@ -0,0 +1,611 @@ +//// [tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts] //// + +=== instanceofOperatorWithRHSHasSymbolHasInstance.ts === +interface Point { x: number, y: number } +>x : number +>y : number + +interface Point3D { x: number, y: number, z: number } +>x : number +>y : number +>z : number + +interface Point3D2 extends Point { z: number } +>z : number + +interface Line { start: Point, end: Point } +>start : Point +>end : Point + +declare var rhs0: { [Symbol.hasInstance](value: unknown): boolean; }; +>rhs0 : { [Symbol.hasInstance](value: unknown): boolean; } +>[Symbol.hasInstance] : (value: unknown) => boolean +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown + +declare var rhs1: { [Symbol.hasInstance](value: any): boolean; }; +>rhs1 : { [Symbol.hasInstance](value: any): boolean; } +>[Symbol.hasInstance] : (value: any) => boolean +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : any + +declare var rhs2: { [Symbol.hasInstance](value: any): value is Point; }; +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>[Symbol.hasInstance] : (value: any) => value is Point +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : any + +declare var rhs3: { [Symbol.hasInstance](value: Point | Line): value is Point; }; +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>[Symbol.hasInstance] : (value: Point | Line) => value is Point +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point | Line + +declare var rhs4: { [Symbol.hasInstance](value: Point | Line): value is Line; }; +>rhs4 : { [Symbol.hasInstance](value: Point | Line): value is Line; } +>[Symbol.hasInstance] : (value: Point | Line) => value is Line +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point | Line + +declare var rhs5: { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; }; +>rhs5 : { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>[Symbol.hasInstance] : (value: Point | Point3D | Line) => value is Point3D +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point | Point3D | Line + +declare var rhs6: { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; }; +>rhs6 : { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } +>[Symbol.hasInstance] : (value: Point3D | Line) => value is Point3D +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point3D | Line + +declare class Rhs7 { static [Symbol.hasInstance](value: unknown): boolean; } +>Rhs7 : Rhs7 +>[Symbol.hasInstance] : (value: unknown) => boolean +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown + +declare class Rhs8 { static [Symbol.hasInstance](value: any): boolean; } +>Rhs8 : Rhs8 +>[Symbol.hasInstance] : (value: any) => boolean +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : any + +declare class Rhs9 { static [Symbol.hasInstance](value: any): value is Point; } +>Rhs9 : Rhs9 +>[Symbol.hasInstance] : (value: any) => value is Point +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : any + +declare class Rhs10 { static [Symbol.hasInstance](value: Point | Line): value is Point; } +>Rhs10 : Rhs10 +>[Symbol.hasInstance] : (value: Point | Line) => value is Point +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point | Line + +declare class Rhs11 { static [Symbol.hasInstance](value: Point | Line): value is Line; } +>Rhs11 : Rhs11 +>[Symbol.hasInstance] : (value: Point | Line) => value is Line +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point | Line + +declare class Rhs12 { static [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>Rhs12 : Rhs12 +>[Symbol.hasInstance] : (value: Point | Point3D | Line) => value is Point3D +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point | Point3D | Line + +declare class Rhs13 { static [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } +>Rhs13 : Rhs13 +>[Symbol.hasInstance] : (value: Point3D | Line) => value is Point3D +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : Point3D | Line + +declare var lhs0: any; +>lhs0 : any + +declare var lhs1: object; +>lhs1 : object + +declare var lhs2: Point | Point3D | Line; +>lhs2 : Point | Point3D | Line + +declare var lhs3: Point3D | Line; +>lhs3 : Point3D | Line + +declare var lhs4: Point | Point3D2 | Line; +>lhs4 : Point | Point3D2 | Line + +lhs0 instanceof rhs0 && lhs0; +>lhs0 instanceof rhs0 && lhs0 : any +>lhs0 instanceof rhs0 : boolean +>lhs0 : any +>rhs0 : { [Symbol.hasInstance](value: unknown): boolean; } +>lhs0 : any + +lhs0 instanceof rhs1 && lhs0; +>lhs0 instanceof rhs1 && lhs0 : any +>lhs0 instanceof rhs1 : boolean +>lhs0 : any +>rhs1 : { [Symbol.hasInstance](value: any): boolean; } +>lhs0 : any + +lhs0 instanceof rhs2 && lhs0; +>lhs0 instanceof rhs2 && lhs0 : Point +>lhs0 instanceof rhs2 : boolean +>lhs0 : any +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs0 : Point + +lhs0 instanceof rhs3 && lhs0; +>lhs0 instanceof rhs3 && lhs0 : Point +>lhs0 instanceof rhs3 : boolean +>lhs0 : any +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>lhs0 : Point + +lhs0 instanceof rhs4 && lhs0; +>lhs0 instanceof rhs4 && lhs0 : Line +>lhs0 instanceof rhs4 : boolean +>lhs0 : any +>rhs4 : { [Symbol.hasInstance](value: Point | Line): value is Line; } +>lhs0 : Line + +lhs0 instanceof rhs5 && lhs0; +>lhs0 instanceof rhs5 && lhs0 : Point3D +>lhs0 instanceof rhs5 : boolean +>lhs0 : any +>rhs5 : { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>lhs0 : Point3D + +lhs0 instanceof rhs6 && lhs0; +>lhs0 instanceof rhs6 && lhs0 : Point3D +>lhs0 instanceof rhs6 : boolean +>lhs0 : any +>rhs6 : { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } +>lhs0 : Point3D + +lhs0 instanceof Rhs7 && lhs0; +>lhs0 instanceof Rhs7 && lhs0 : Rhs7 +>lhs0 instanceof Rhs7 : boolean +>lhs0 : any +>Rhs7 : typeof Rhs7 +>lhs0 : Rhs7 + +lhs0 instanceof Rhs8 && lhs0; +>lhs0 instanceof Rhs8 && lhs0 : Rhs8 +>lhs0 instanceof Rhs8 : boolean +>lhs0 : any +>Rhs8 : typeof Rhs8 +>lhs0 : Rhs8 + +lhs0 instanceof Rhs9 && lhs0; +>lhs0 instanceof Rhs9 && lhs0 : Point +>lhs0 instanceof Rhs9 : boolean +>lhs0 : any +>Rhs9 : typeof Rhs9 +>lhs0 : Point + +lhs0 instanceof Rhs10 && lhs0; +>lhs0 instanceof Rhs10 && lhs0 : Point +>lhs0 instanceof Rhs10 : boolean +>lhs0 : any +>Rhs10 : typeof Rhs10 +>lhs0 : Point + +lhs0 instanceof Rhs11 && lhs0; +>lhs0 instanceof Rhs11 && lhs0 : Line +>lhs0 instanceof Rhs11 : boolean +>lhs0 : any +>Rhs11 : typeof Rhs11 +>lhs0 : Line + +lhs0 instanceof Rhs12 && lhs0; +>lhs0 instanceof Rhs12 && lhs0 : Point3D +>lhs0 instanceof Rhs12 : boolean +>lhs0 : any +>Rhs12 : typeof Rhs12 +>lhs0 : Point3D + +lhs0 instanceof Rhs13 && lhs0; +>lhs0 instanceof Rhs13 && lhs0 : Point3D +>lhs0 instanceof Rhs13 : boolean +>lhs0 : any +>Rhs13 : typeof Rhs13 +>lhs0 : Point3D + +lhs1 instanceof rhs0 && lhs1; +>lhs1 instanceof rhs0 && lhs1 : object +>lhs1 instanceof rhs0 : boolean +>lhs1 : object +>rhs0 : { [Symbol.hasInstance](value: unknown): boolean; } +>lhs1 : object + +lhs1 instanceof rhs1 && lhs1; +>lhs1 instanceof rhs1 && lhs1 : object +>lhs1 instanceof rhs1 : boolean +>lhs1 : object +>rhs1 : { [Symbol.hasInstance](value: any): boolean; } +>lhs1 : object + +lhs1 instanceof rhs2 && lhs1; +>lhs1 instanceof rhs2 && lhs1 : Point +>lhs1 instanceof rhs2 : boolean +>lhs1 : object +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs1 : Point + +lhs1 instanceof Rhs7 && lhs1; +>lhs1 instanceof Rhs7 && lhs1 : Rhs7 +>lhs1 instanceof Rhs7 : boolean +>lhs1 : object +>Rhs7 : typeof Rhs7 +>lhs1 : Rhs7 + +lhs1 instanceof Rhs8 && lhs1; +>lhs1 instanceof Rhs8 && lhs1 : Rhs8 +>lhs1 instanceof Rhs8 : boolean +>lhs1 : object +>Rhs8 : typeof Rhs8 +>lhs1 : Rhs8 + +lhs1 instanceof Rhs9 && lhs1; +>lhs1 instanceof Rhs9 && lhs1 : Point +>lhs1 instanceof Rhs9 : boolean +>lhs1 : object +>Rhs9 : typeof Rhs9 +>lhs1 : Point + +lhs2 instanceof rhs0 && lhs2; +>lhs2 instanceof rhs0 && lhs2 : Point | Point3D | Line +>lhs2 instanceof rhs0 : boolean +>lhs2 : Point | Point3D | Line +>rhs0 : { [Symbol.hasInstance](value: unknown): boolean; } +>lhs2 : Point | Point3D | Line + +lhs2 instanceof rhs1 && lhs2; +>lhs2 instanceof rhs1 && lhs2 : Point | Point3D | Line +>lhs2 instanceof rhs1 : boolean +>lhs2 : Point | Point3D | Line +>rhs1 : { [Symbol.hasInstance](value: any): boolean; } +>lhs2 : Point | Point3D | Line + +lhs2 instanceof rhs2 && lhs2; +>lhs2 instanceof rhs2 && lhs2 : Point +>lhs2 instanceof rhs2 : boolean +>lhs2 : Point | Point3D | Line +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs2 : Point + +lhs2 instanceof rhs3 && lhs2; +>lhs2 instanceof rhs3 && lhs2 : Point +>lhs2 instanceof rhs3 : boolean +>lhs2 : Point | Point3D | Line +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>lhs2 : Point + +lhs2 instanceof rhs4 && lhs2; +>lhs2 instanceof rhs4 && lhs2 : Line +>lhs2 instanceof rhs4 : boolean +>lhs2 : Point | Point3D | Line +>rhs4 : { [Symbol.hasInstance](value: Point | Line): value is Line; } +>lhs2 : Line + +lhs2 instanceof rhs5 && lhs2; +>lhs2 instanceof rhs5 && lhs2 : Point3D +>lhs2 instanceof rhs5 : boolean +>lhs2 : Point | Point3D | Line +>rhs5 : { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>lhs2 : Point3D + +lhs2 instanceof Rhs7 && lhs2; +>lhs2 instanceof Rhs7 && lhs2 : Point | Point3D | Line +>lhs2 instanceof Rhs7 : boolean +>lhs2 : Point | Point3D | Line +>Rhs7 : typeof Rhs7 +>lhs2 : Point | Point3D | Line + +lhs2 instanceof Rhs8 && lhs2; +>lhs2 instanceof Rhs8 && lhs2 : Point | Point3D | Line +>lhs2 instanceof Rhs8 : boolean +>lhs2 : Point | Point3D | Line +>Rhs8 : typeof Rhs8 +>lhs2 : Point | Point3D | Line + +lhs2 instanceof Rhs9 && lhs2; +>lhs2 instanceof Rhs9 && lhs2 : Point +>lhs2 instanceof Rhs9 : boolean +>lhs2 : Point | Point3D | Line +>Rhs9 : typeof Rhs9 +>lhs2 : Point + +lhs2 instanceof Rhs10 && lhs2; +>lhs2 instanceof Rhs10 && lhs2 : Point +>lhs2 instanceof Rhs10 : boolean +>lhs2 : Point | Point3D | Line +>Rhs10 : typeof Rhs10 +>lhs2 : Point + +lhs2 instanceof Rhs11 && lhs2; +>lhs2 instanceof Rhs11 && lhs2 : Line +>lhs2 instanceof Rhs11 : boolean +>lhs2 : Point | Point3D | Line +>Rhs11 : typeof Rhs11 +>lhs2 : Line + +lhs2 instanceof Rhs12 && lhs2; +>lhs2 instanceof Rhs12 && lhs2 : Point3D +>lhs2 instanceof Rhs12 : boolean +>lhs2 : Point | Point3D | Line +>Rhs12 : typeof Rhs12 +>lhs2 : Point3D + +lhs3 instanceof rhs0 && lhs3; +>lhs3 instanceof rhs0 && lhs3 : Point3D | Line +>lhs3 instanceof rhs0 : boolean +>lhs3 : Point3D | Line +>rhs0 : { [Symbol.hasInstance](value: unknown): boolean; } +>lhs3 : Point3D | Line + +lhs3 instanceof rhs1 && lhs3; +>lhs3 instanceof rhs1 && lhs3 : Point3D | Line +>lhs3 instanceof rhs1 : boolean +>lhs3 : Point3D | Line +>rhs1 : { [Symbol.hasInstance](value: any): boolean; } +>lhs3 : Point3D | Line + +lhs3 instanceof rhs2 && lhs3; +>lhs3 instanceof rhs2 && lhs3 : (Point3D | Line) & Point +>lhs3 instanceof rhs2 : boolean +>lhs3 : Point3D | Line +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs3 : (Point3D | Line) & Point + +lhs3 instanceof rhs3 && lhs3; +>lhs3 instanceof rhs3 && lhs3 : (Point3D | Line) & Point +>lhs3 instanceof rhs3 : boolean +>lhs3 : Point3D | Line +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>lhs3 : (Point3D | Line) & Point + +lhs3 instanceof rhs4 && lhs3; +>lhs3 instanceof rhs4 && lhs3 : Line +>lhs3 instanceof rhs4 : boolean +>lhs3 : Point3D | Line +>rhs4 : { [Symbol.hasInstance](value: Point | Line): value is Line; } +>lhs3 : Line + +lhs3 instanceof rhs5 && lhs3; +>lhs3 instanceof rhs5 && lhs3 : Point3D +>lhs3 instanceof rhs5 : boolean +>lhs3 : Point3D | Line +>rhs5 : { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>lhs3 : Point3D + +lhs3 instanceof rhs6 && lhs3; +>lhs3 instanceof rhs6 && lhs3 : Point3D +>lhs3 instanceof rhs6 : boolean +>lhs3 : Point3D | Line +>rhs6 : { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } +>lhs3 : Point3D + +lhs3 instanceof Rhs7 && lhs3; +>lhs3 instanceof Rhs7 && lhs3 : Point3D | Line +>lhs3 instanceof Rhs7 : boolean +>lhs3 : Point3D | Line +>Rhs7 : typeof Rhs7 +>lhs3 : Point3D | Line + +lhs3 instanceof Rhs8 && lhs3; +>lhs3 instanceof Rhs8 && lhs3 : Point3D | Line +>lhs3 instanceof Rhs8 : boolean +>lhs3 : Point3D | Line +>Rhs8 : typeof Rhs8 +>lhs3 : Point3D | Line + +lhs3 instanceof Rhs9 && lhs3; +>lhs3 instanceof Rhs9 && lhs3 : (Point3D | Line) & Point +>lhs3 instanceof Rhs9 : boolean +>lhs3 : Point3D | Line +>Rhs9 : typeof Rhs9 +>lhs3 : (Point3D | Line) & Point + +lhs3 instanceof Rhs10 && lhs3; +>lhs3 instanceof Rhs10 && lhs3 : (Point3D | Line) & Point +>lhs3 instanceof Rhs10 : boolean +>lhs3 : Point3D | Line +>Rhs10 : typeof Rhs10 +>lhs3 : (Point3D | Line) & Point + +lhs3 instanceof Rhs11 && lhs3; +>lhs3 instanceof Rhs11 && lhs3 : Line +>lhs3 instanceof Rhs11 : boolean +>lhs3 : Point3D | Line +>Rhs11 : typeof Rhs11 +>lhs3 : Line + +lhs3 instanceof Rhs12 && lhs3; +>lhs3 instanceof Rhs12 && lhs3 : Point3D +>lhs3 instanceof Rhs12 : boolean +>lhs3 : Point3D | Line +>Rhs12 : typeof Rhs12 +>lhs3 : Point3D + +lhs3 instanceof Rhs13 && lhs3; +>lhs3 instanceof Rhs13 && lhs3 : Point3D +>lhs3 instanceof Rhs13 : boolean +>lhs3 : Point3D | Line +>Rhs13 : typeof Rhs13 +>lhs3 : Point3D + +lhs4 instanceof rhs0 && lhs4; +>lhs4 instanceof rhs0 && lhs4 : Point | Point3D2 | Line +>lhs4 instanceof rhs0 : boolean +>lhs4 : Point | Point3D2 | Line +>rhs0 : { [Symbol.hasInstance](value: unknown): boolean; } +>lhs4 : Point | Point3D2 | Line + +lhs4 instanceof rhs1 && lhs4; +>lhs4 instanceof rhs1 && lhs4 : Point | Point3D2 | Line +>lhs4 instanceof rhs1 : boolean +>lhs4 : Point | Point3D2 | Line +>rhs1 : { [Symbol.hasInstance](value: any): boolean; } +>lhs4 : Point | Point3D2 | Line + +lhs4 instanceof rhs2 && lhs4; +>lhs4 instanceof rhs2 && lhs4 : Point | Point3D2 +>lhs4 instanceof rhs2 : boolean +>lhs4 : Point | Point3D2 | Line +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs4 : Point | Point3D2 + +lhs4 instanceof rhs3 && lhs4; +>lhs4 instanceof rhs3 && lhs4 : Point | Point3D2 +>lhs4 instanceof rhs3 : boolean +>lhs4 : Point | Point3D2 | Line +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>lhs4 : Point | Point3D2 + +lhs4 instanceof rhs4 && lhs4; +>lhs4 instanceof rhs4 && lhs4 : Line +>lhs4 instanceof rhs4 : boolean +>lhs4 : Point | Point3D2 | Line +>rhs4 : { [Symbol.hasInstance](value: Point | Line): value is Line; } +>lhs4 : Line + +lhs4 instanceof rhs5 && lhs4; +>lhs4 instanceof rhs5 && lhs4 : Point3D +>lhs4 instanceof rhs5 : boolean +>lhs4 : Point | Point3D2 | Line +>rhs5 : { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>lhs4 : Point3D + +lhs4 instanceof Rhs7 && lhs4; +>lhs4 instanceof Rhs7 && lhs4 : Point | Point3D2 | Line +>lhs4 instanceof Rhs7 : boolean +>lhs4 : Point | Point3D2 | Line +>Rhs7 : typeof Rhs7 +>lhs4 : Point | Point3D2 | Line + +lhs4 instanceof Rhs8 && lhs4; +>lhs4 instanceof Rhs8 && lhs4 : Point | Point3D2 | Line +>lhs4 instanceof Rhs8 : boolean +>lhs4 : Point | Point3D2 | Line +>Rhs8 : typeof Rhs8 +>lhs4 : Point | Point3D2 | Line + +lhs4 instanceof Rhs9 && lhs4; +>lhs4 instanceof Rhs9 && lhs4 : Point | Point3D2 +>lhs4 instanceof Rhs9 : boolean +>lhs4 : Point | Point3D2 | Line +>Rhs9 : typeof Rhs9 +>lhs4 : Point | Point3D2 + +lhs4 instanceof Rhs10 && lhs4; +>lhs4 instanceof Rhs10 && lhs4 : Point | Point3D2 +>lhs4 instanceof Rhs10 : boolean +>lhs4 : Point | Point3D2 | Line +>Rhs10 : typeof Rhs10 +>lhs4 : Point | Point3D2 + +lhs4 instanceof Rhs11 && lhs4; +>lhs4 instanceof Rhs11 && lhs4 : Line +>lhs4 instanceof Rhs11 : boolean +>lhs4 : Point | Point3D2 | Line +>Rhs11 : typeof Rhs11 +>lhs4 : Line + +lhs4 instanceof Rhs12 && lhs4; +>lhs4 instanceof Rhs12 && lhs4 : Point3D +>lhs4 instanceof Rhs12 : boolean +>lhs4 : Point | Point3D2 | Line +>Rhs12 : typeof Rhs12 +>lhs4 : Point3D + +declare class A { +>A : A + + #x: number; +>#x : number + + // approximation of `getInstanceType` behavior, with one caveat: the checker versions unions the return types of + // all construct signatures, but we have no way of extracting individual construct signatures from a type. + static [Symbol.hasInstance](this: T, value: unknown): value is ( +>[Symbol.hasInstance] : (this: T, value: unknown) => value is T extends Function ? T extends { readonly prototype: infer U; } ? boolean extends (U extends never ? true : false) ? T extends abstract new (...args: any) => infer V ? V : {} : U : never : never +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>this : T +>value : unknown + + T extends globalThis.Function ? +>globalThis : any + + T extends { readonly prototype: infer U } ? +>prototype : U + + boolean extends (U extends never ? true : false) ? // <- tests whether 'U' is 'any' +>true : true +>false : false + + T extends (abstract new (...args: any) => infer V) ? V : {} : +>args : any + + U : + never : + never + ); +} + +declare class B extends A { #y: number; } +>B : B +>A : A +>#y : number + +declare const obj: unknown; +>obj : unknown + +if (obj instanceof A) { +>obj instanceof A : boolean +>obj : unknown +>A : typeof A + + obj; // A +>obj : A +} +if (obj instanceof B) { +>obj instanceof B : boolean +>obj : unknown +>B : typeof B + + obj; // B +>obj : B +} diff --git a/tests/baselines/reference/symbolType1.errors.txt b/tests/baselines/reference/symbolType1.errors.txt index cde9160e0b2fb..3aaaf7c5502c1 100644 --- a/tests/baselines/reference/symbolType1.errors.txt +++ b/tests/baselines/reference/symbolType1.errors.txt @@ -1,6 +1,6 @@ symbolType1.ts(1,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -symbolType1.ts(2,19): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -symbolType1.ts(4,19): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +symbolType1.ts(2,19): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. +symbolType1.ts(4,19): error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. ==== symbolType1.ts (3 errors) ==== @@ -9,8 +9,8 @@ symbolType1.ts(4,19): error TS2359: The right-hand side of an 'instanceof' expre !!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. Symbol instanceof Symbol(); ~~~~~~~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. (Symbol() || {}) instanceof Object; // This one should be okay, it's a valid way of distinguishing types Symbol instanceof (Symbol() || {}); ~~~~~~~~~~~~~~~~ -!!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. \ No newline at end of file +!!! error TS2359: The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method. \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt index 9e762ce5f4dca..f0c93a11efe23 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt +++ b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.errors.txt @@ -98,7 +98,7 @@ typeGuardsWithInstanceOfByConstructorSignature.ts(188,11): error TS2551: Propert declare var C: CConstructor; var obj5: C1 | A; - if (obj5 instanceof C) { // narrowed to C1|C2. + if (obj5 instanceof C) { // narrowed to C1. obj5.foo; obj5.c; obj5.bar1; @@ -157,7 +157,7 @@ typeGuardsWithInstanceOfByConstructorSignature.ts(188,11): error TS2551: Propert declare var E: EConstructor; var obj9: E1 | A; - if (obj9 instanceof E) { // narrowed to E1 | E2 + if (obj9 instanceof E) { // narrowed to E1 obj9.foo; obj9.bar1; obj9.bar2; diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.js b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.js index 957542de8dcab..1beff0fd46200 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.js +++ b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.js @@ -62,7 +62,7 @@ interface C2 { declare var C: CConstructor; var obj5: C1 | A; -if (obj5 instanceof C) { // narrowed to C1|C2. +if (obj5 instanceof C) { // narrowed to C1. obj5.foo; obj5.c; obj5.bar1; @@ -109,7 +109,7 @@ interface E2 { declare var E: EConstructor; var obj9: E1 | A; -if (obj9 instanceof E) { // narrowed to E1 | E2 +if (obj9 instanceof E) { // narrowed to E1 obj9.foo; obj9.bar1; obj9.bar2; @@ -228,7 +228,7 @@ if (obj4 instanceof B) { obj4.bar = "str"; } var obj5; -if (obj5 instanceof C) { // narrowed to C1|C2. +if (obj5 instanceof C) { // narrowed to C1. obj5.foo; obj5.c; obj5.bar1; @@ -251,7 +251,7 @@ if (obj8 instanceof D) { obj8.bar; } var obj9; -if (obj9 instanceof E) { // narrowed to E1 | E2 +if (obj9 instanceof E) { // narrowed to E1 obj9.foo; obj9.bar1; obj9.bar2; diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.symbols b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.symbols index 455946206c82b..c2aa82dad9f5d 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.symbols +++ b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.symbols @@ -159,7 +159,7 @@ var obj5: C1 | A; >C1 : Symbol(C1, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 47, 1)) >A : Symbol(A, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 2, 1), Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 6, 11)) -if (obj5 instanceof C) { // narrowed to C1|C2. +if (obj5 instanceof C) { // narrowed to C1. >obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 60, 3)) >C : Symbol(C, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 58, 11)) @@ -280,7 +280,7 @@ var obj9: E1 | A; >E1 : Symbol(E1, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 96, 1)) >A : Symbol(A, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 2, 1), Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 6, 11)) -if (obj9 instanceof E) { // narrowed to E1 | E2 +if (obj9 instanceof E) { // narrowed to E1 >obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 107, 3)) >E : Symbol(E, Decl(typeGuardsWithInstanceOfByConstructorSignature.ts, 105, 11)) diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types index a3ed2b1ae0359..1d76e5385aeb5 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types +++ b/tests/baselines/reference/typeGuardsWithInstanceOfByConstructorSignature.types @@ -154,7 +154,7 @@ declare var C: CConstructor; var obj5: C1 | A; >obj5 : A | C1 -if (obj5 instanceof C) { // narrowed to C1|C2. +if (obj5 instanceof C) { // narrowed to C1. >obj5 instanceof C : boolean >obj5 : A | C1 >C : CConstructor @@ -274,7 +274,7 @@ declare var E: EConstructor; var obj9: E1 | A; >obj9 : A | E1 -if (obj9 instanceof E) { // narrowed to E1 | E2 +if (obj9 instanceof E) { // narrowed to E1 >obj9 instanceof E : boolean >obj9 : A | E1 >E : EConstructor diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt new file mode 100644 index 0000000000000..f4ec1af5217f5 --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt @@ -0,0 +1,289 @@ +typeGuardsWithInstanceOfBySymbolHasInstance.ts(13,10): error TS2339: Property 'bar' does not exist on type 'A'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(19,10): error TS2339: Property 'bar' does not exist on type 'A'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(35,5): error TS2322: Type 'string' is not assignable to type 'number'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(36,10): error TS2339: Property 'bar' does not exist on type 'B'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(43,10): error TS2339: Property 'bar' does not exist on type 'B'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(69,10): error TS2339: Property 'bar2' does not exist on type 'C1'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(75,10): error TS2339: Property 'bar1' does not exist on type 'C1 | C2'. + Property 'bar1' does not exist on type 'C2'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(76,10): error TS2339: Property 'bar2' does not exist on type 'C1 | C2'. + Property 'bar2' does not exist on type 'C1'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(91,10): error TS2339: Property 'bar' does not exist on type 'D'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(97,10): error TS2339: Property 'bar' does not exist on type 'D'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(119,10): error TS2339: Property 'bar2' does not exist on type 'E1'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(125,11): error TS2339: Property 'bar1' does not exist on type 'E1 | E2'. + Property 'bar1' does not exist on type 'E2'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(126,11): error TS2339: Property 'bar2' does not exist on type 'E1 | E2'. + Property 'bar2' does not exist on type 'E1'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(142,11): error TS2339: Property 'foo' does not exist on type 'string | F'. + Property 'foo' does not exist on type 'string'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(143,11): error TS2339: Property 'bar' does not exist on type 'string | F'. + Property 'bar' does not exist on type 'string'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(169,11): error TS2339: Property 'foo2' does not exist on type 'G1'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(175,11): error TS2339: Property 'foo2' does not exist on type 'G1'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(192,11): error TS2339: Property 'bar' does not exist on type 'H'. +typeGuardsWithInstanceOfBySymbolHasInstance.ts(197,11): error TS2551: Property 'foo1' does not exist on type 'H'. Did you mean 'foo'? +typeGuardsWithInstanceOfBySymbolHasInstance.ts(198,11): error TS2551: Property 'foo2' does not exist on type 'H'. Did you mean 'foo'? + + +==== typeGuardsWithInstanceOfBySymbolHasInstance.ts (20 errors) ==== + interface AConstructor { + new (): A; + [Symbol.hasInstance](value: unknown): value is A; + } + interface A { + foo: string; + } + declare var A: AConstructor; + + var obj1: A | string; + if (obj1 instanceof A) { // narrowed to A. + obj1.foo; + obj1.bar; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'A'. + } + + var obj2: any; + if (obj2 instanceof A) { + obj2.foo; + obj2.bar; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'A'. + } + + // a construct signature with generics + interface BConstructor { + new (): B; + [Symbol.hasInstance](value: unknown): value is B; + } + interface B { + foo: T; + } + declare var B: BConstructor; + + var obj3: B | string; + if (obj3 instanceof B) { // narrowed to B. + obj3.foo = 1; + obj3.foo = "str"; + ~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + obj3.bar = "str"; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'B'. + } + + var obj4: any; + if (obj4 instanceof B) { + obj4.foo = "str"; + obj4.foo = 1; + obj4.bar = "str"; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'B'. + } + + // has multiple construct signature + interface CConstructor { + new (value: string): C1; + new (value: number): C2; + [Symbol.hasInstance](value: unknown): value is C1 | C2; + } + interface C1 { + foo: string; + c: string; + bar1: number; + } + interface C2 { + foo: string; + c: string; + bar2: number; + } + declare var C: CConstructor; + + var obj5: C1 | A; + if (obj5 instanceof C) { // narrowed to C1. + obj5.foo; + obj5.c; + obj5.bar1; + obj5.bar2; + ~~~~ +!!! error TS2339: Property 'bar2' does not exist on type 'C1'. + } + + var obj6: any; + if (obj6 instanceof C) { + obj6.foo; + obj6.bar1; + ~~~~ +!!! error TS2339: Property 'bar1' does not exist on type 'C1 | C2'. +!!! error TS2339: Property 'bar1' does not exist on type 'C2'. + obj6.bar2; + ~~~~ +!!! error TS2339: Property 'bar2' does not exist on type 'C1 | C2'. +!!! error TS2339: Property 'bar2' does not exist on type 'C1'. + } + + // with object type literal + interface D { + foo: string; + } + declare var D: { + new (): D; + [Symbol.hasInstance](value: unknown): value is D; + }; + + var obj7: D | string; + if (obj7 instanceof D) { // narrowed to D. + obj7.foo; + obj7.bar; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'D'. + } + + var obj8: any; + if (obj8 instanceof D) { + obj8.foo; + obj8.bar; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'D'. + } + + // a construct signature that returns a union type + interface EConstructor { + new (): E1 | E2; + [Symbol.hasInstance](value: unknown): value is E1 | E2; + } + interface E1 { + foo: string; + bar1: number; + } + interface E2 { + foo: string; + bar2: number; + } + declare var E: EConstructor; + + var obj9: E1 | A; + if (obj9 instanceof E) { // narrowed to E1 + obj9.foo; + obj9.bar1; + obj9.bar2; + ~~~~ +!!! error TS2339: Property 'bar2' does not exist on type 'E1'. + } + + var obj10: any; + if (obj10 instanceof E) { + obj10.foo; + obj10.bar1; + ~~~~ +!!! error TS2339: Property 'bar1' does not exist on type 'E1 | E2'. +!!! error TS2339: Property 'bar1' does not exist on type 'E2'. + obj10.bar2; + ~~~~ +!!! error TS2339: Property 'bar2' does not exist on type 'E1 | E2'. +!!! error TS2339: Property 'bar2' does not exist on type 'E1'. + } + + // a construct signature that returns any + interface FConstructor { + new (): any; + [Symbol.hasInstance](value: unknown): value is any; + } + interface F { + foo: string; + bar: number; + } + declare var F: FConstructor; + + var obj11: F | string; + if (obj11 instanceof F) { // can't type narrowing, construct signature returns any. + obj11.foo; + ~~~ +!!! error TS2339: Property 'foo' does not exist on type 'string | F'. +!!! error TS2339: Property 'foo' does not exist on type 'string'. + obj11.bar; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'string | F'. +!!! error TS2339: Property 'bar' does not exist on type 'string'. + } + + var obj12: any; + if (obj12 instanceof F) { + obj12.foo; + obj12.bar; + } + + // a type with a prototype, it overrides the construct signature + interface GConstructor { + prototype: G1; // high priority + new (): G2; // low priority + [Symbol.hasInstance](value: unknown): value is G1; // overrides priority + } + interface G1 { + foo1: number; + } + interface G2 { + foo2: boolean; + } + declare var G: GConstructor; + + var obj13: G1 | G2; + if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. + obj13.foo1; + obj13.foo2; + ~~~~ +!!! error TS2339: Property 'foo2' does not exist on type 'G1'. + } + + var obj14: any; + if (obj14 instanceof G) { + obj14.foo1; + obj14.foo2; + ~~~~ +!!! error TS2339: Property 'foo2' does not exist on type 'G1'. + } + + // a type with a prototype that has any type + interface HConstructor { + prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`. + new (): H; // low priority + [Symbol.hasInstance](value: unknown): value is H; // overrides priority + } + interface H { + foo: number; + } + declare var H: HConstructor; + + var obj15: H | string; + if (obj15 instanceof H) { // narrowed to H. + obj15.foo; + obj15.bar; + ~~~ +!!! error TS2339: Property 'bar' does not exist on type 'H'. + } + + var obj16: any; + if (obj16 instanceof H) { + obj16.foo1; + ~~~~ +!!! error TS2551: Property 'foo1' does not exist on type 'H'. Did you mean 'foo'? +!!! related TS2728 typeGuardsWithInstanceOfBySymbolHasInstance.ts:185:5: 'foo' is declared here. + obj16.foo2; + ~~~~ +!!! error TS2551: Property 'foo2' does not exist on type 'H'. Did you mean 'foo'? +!!! related TS2728 typeGuardsWithInstanceOfBySymbolHasInstance.ts:185:5: 'foo' is declared here. + } + + var obj17: any; + if (obj17 instanceof Object) { // can't narrow type from 'any' to 'Object' + obj17.foo1; + obj17.foo2; + } + + var obj18: any; + if (obj18 instanceof Function) { // can't narrow type from 'any' to 'Function' + obj18.foo1; + obj18.foo2; + } + \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js new file mode 100644 index 0000000000000..07f4b5178a2e2 --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js @@ -0,0 +1,314 @@ +//// [tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts] //// + +//// [typeGuardsWithInstanceOfBySymbolHasInstance.ts] +interface AConstructor { + new (): A; + [Symbol.hasInstance](value: unknown): value is A; +} +interface A { + foo: string; +} +declare var A: AConstructor; + +var obj1: A | string; +if (obj1 instanceof A) { // narrowed to A. + obj1.foo; + obj1.bar; +} + +var obj2: any; +if (obj2 instanceof A) { + obj2.foo; + obj2.bar; +} + +// a construct signature with generics +interface BConstructor { + new (): B; + [Symbol.hasInstance](value: unknown): value is B; +} +interface B { + foo: T; +} +declare var B: BConstructor; + +var obj3: B | string; +if (obj3 instanceof B) { // narrowed to B. + obj3.foo = 1; + obj3.foo = "str"; + obj3.bar = "str"; +} + +var obj4: any; +if (obj4 instanceof B) { + obj4.foo = "str"; + obj4.foo = 1; + obj4.bar = "str"; +} + +// has multiple construct signature +interface CConstructor { + new (value: string): C1; + new (value: number): C2; + [Symbol.hasInstance](value: unknown): value is C1 | C2; +} +interface C1 { + foo: string; + c: string; + bar1: number; +} +interface C2 { + foo: string; + c: string; + bar2: number; +} +declare var C: CConstructor; + +var obj5: C1 | A; +if (obj5 instanceof C) { // narrowed to C1. + obj5.foo; + obj5.c; + obj5.bar1; + obj5.bar2; +} + +var obj6: any; +if (obj6 instanceof C) { + obj6.foo; + obj6.bar1; + obj6.bar2; +} + +// with object type literal +interface D { + foo: string; +} +declare var D: { + new (): D; + [Symbol.hasInstance](value: unknown): value is D; +}; + +var obj7: D | string; +if (obj7 instanceof D) { // narrowed to D. + obj7.foo; + obj7.bar; +} + +var obj8: any; +if (obj8 instanceof D) { + obj8.foo; + obj8.bar; +} + +// a construct signature that returns a union type +interface EConstructor { + new (): E1 | E2; + [Symbol.hasInstance](value: unknown): value is E1 | E2; +} +interface E1 { + foo: string; + bar1: number; +} +interface E2 { + foo: string; + bar2: number; +} +declare var E: EConstructor; + +var obj9: E1 | A; +if (obj9 instanceof E) { // narrowed to E1 + obj9.foo; + obj9.bar1; + obj9.bar2; +} + +var obj10: any; +if (obj10 instanceof E) { + obj10.foo; + obj10.bar1; + obj10.bar2; +} + +// a construct signature that returns any +interface FConstructor { + new (): any; + [Symbol.hasInstance](value: unknown): value is any; +} +interface F { + foo: string; + bar: number; +} +declare var F: FConstructor; + +var obj11: F | string; +if (obj11 instanceof F) { // can't type narrowing, construct signature returns any. + obj11.foo; + obj11.bar; +} + +var obj12: any; +if (obj12 instanceof F) { + obj12.foo; + obj12.bar; +} + +// a type with a prototype, it overrides the construct signature +interface GConstructor { + prototype: G1; // high priority + new (): G2; // low priority + [Symbol.hasInstance](value: unknown): value is G1; // overrides priority +} +interface G1 { + foo1: number; +} +interface G2 { + foo2: boolean; +} +declare var G: GConstructor; + +var obj13: G1 | G2; +if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. + obj13.foo1; + obj13.foo2; +} + +var obj14: any; +if (obj14 instanceof G) { + obj14.foo1; + obj14.foo2; +} + +// a type with a prototype that has any type +interface HConstructor { + prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`. + new (): H; // low priority + [Symbol.hasInstance](value: unknown): value is H; // overrides priority +} +interface H { + foo: number; +} +declare var H: HConstructor; + +var obj15: H | string; +if (obj15 instanceof H) { // narrowed to H. + obj15.foo; + obj15.bar; +} + +var obj16: any; +if (obj16 instanceof H) { + obj16.foo1; + obj16.foo2; +} + +var obj17: any; +if (obj17 instanceof Object) { // can't narrow type from 'any' to 'Object' + obj17.foo1; + obj17.foo2; +} + +var obj18: any; +if (obj18 instanceof Function) { // can't narrow type from 'any' to 'Function' + obj18.foo1; + obj18.foo2; +} + + +//// [typeGuardsWithInstanceOfBySymbolHasInstance.js] +var obj1; +if (obj1 instanceof A) { // narrowed to A. + obj1.foo; + obj1.bar; +} +var obj2; +if (obj2 instanceof A) { + obj2.foo; + obj2.bar; +} +var obj3; +if (obj3 instanceof B) { // narrowed to B. + obj3.foo = 1; + obj3.foo = "str"; + obj3.bar = "str"; +} +var obj4; +if (obj4 instanceof B) { + obj4.foo = "str"; + obj4.foo = 1; + obj4.bar = "str"; +} +var obj5; +if (obj5 instanceof C) { // narrowed to C1. + obj5.foo; + obj5.c; + obj5.bar1; + obj5.bar2; +} +var obj6; +if (obj6 instanceof C) { + obj6.foo; + obj6.bar1; + obj6.bar2; +} +var obj7; +if (obj7 instanceof D) { // narrowed to D. + obj7.foo; + obj7.bar; +} +var obj8; +if (obj8 instanceof D) { + obj8.foo; + obj8.bar; +} +var obj9; +if (obj9 instanceof E) { // narrowed to E1 + obj9.foo; + obj9.bar1; + obj9.bar2; +} +var obj10; +if (obj10 instanceof E) { + obj10.foo; + obj10.bar1; + obj10.bar2; +} +var obj11; +if (obj11 instanceof F) { // can't type narrowing, construct signature returns any. + obj11.foo; + obj11.bar; +} +var obj12; +if (obj12 instanceof F) { + obj12.foo; + obj12.bar; +} +var obj13; +if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. + obj13.foo1; + obj13.foo2; +} +var obj14; +if (obj14 instanceof G) { + obj14.foo1; + obj14.foo2; +} +var obj15; +if (obj15 instanceof H) { // narrowed to H. + obj15.foo; + obj15.bar; +} +var obj16; +if (obj16 instanceof H) { + obj16.foo1; + obj16.foo2; +} +var obj17; +if (obj17 instanceof Object) { // can't narrow type from 'any' to 'Object' + obj17.foo1; + obj17.foo2; +} +var obj18; +if (obj18 instanceof Function) { // can't narrow type from 'any' to 'Function' + obj18.foo1; + obj18.foo2; +} diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols new file mode 100644 index 0000000000000..6be6f0afde989 --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols @@ -0,0 +1,583 @@ +//// [tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts] //// + +=== typeGuardsWithInstanceOfBySymbolHasInstance.ts === +interface AConstructor { +>AConstructor : Symbol(AConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 0, 0)) + + new (): A; +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + + [Symbol.hasInstance](value: unknown): value is A; +>[Symbol.hasInstance] : Symbol(AConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 1, 14)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 2, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 2, 25)) +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) +} +interface A { +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + + foo: string; +>foo : Symbol(A.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 4, 13)) +} +declare var A: AConstructor; +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) +>AConstructor : Symbol(AConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 0, 0)) + +var obj1: A | string; +>obj1 : Symbol(obj1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 9, 3)) +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + +if (obj1 instanceof A) { // narrowed to A. +>obj1 : Symbol(obj1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 9, 3)) +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + + obj1.foo; +>obj1.foo : Symbol(A.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 4, 13)) +>obj1 : Symbol(obj1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 9, 3)) +>foo : Symbol(A.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 4, 13)) + + obj1.bar; +>obj1 : Symbol(obj1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 9, 3)) +} + +var obj2: any; +>obj2 : Symbol(obj2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 15, 3)) + +if (obj2 instanceof A) { +>obj2 : Symbol(obj2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 15, 3)) +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + + obj2.foo; +>obj2.foo : Symbol(A.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 4, 13)) +>obj2 : Symbol(obj2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 15, 3)) +>foo : Symbol(A.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 4, 13)) + + obj2.bar; +>obj2 : Symbol(obj2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 15, 3)) +} + +// a construct signature with generics +interface BConstructor { +>BConstructor : Symbol(BConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 19, 1)) + + new (): B; +>T : Symbol(T, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 23, 9)) +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) +>T : Symbol(T, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 23, 9)) + + [Symbol.hasInstance](value: unknown): value is B; +>[Symbol.hasInstance] : Symbol(BConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 23, 20)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 24, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 24, 25)) +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) +} +interface B { +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) +>T : Symbol(T, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 12)) + + foo: T; +>foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) +>T : Symbol(T, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 12)) +} +declare var B: BConstructor; +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) +>BConstructor : Symbol(BConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 19, 1)) + +var obj3: B | string; +>obj3 : Symbol(obj3, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 31, 3)) +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) + +if (obj3 instanceof B) { // narrowed to B. +>obj3 : Symbol(obj3, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 31, 3)) +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) + + obj3.foo = 1; +>obj3.foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) +>obj3 : Symbol(obj3, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 31, 3)) +>foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) + + obj3.foo = "str"; +>obj3.foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) +>obj3 : Symbol(obj3, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 31, 3)) +>foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) + + obj3.bar = "str"; +>obj3 : Symbol(obj3, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 31, 3)) +} + +var obj4: any; +>obj4 : Symbol(obj4, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 38, 3)) + +if (obj4 instanceof B) { +>obj4 : Symbol(obj4, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 38, 3)) +>B : Symbol(B, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 25, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 29, 11)) + + obj4.foo = "str"; +>obj4.foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) +>obj4 : Symbol(obj4, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 38, 3)) +>foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) + + obj4.foo = 1; +>obj4.foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) +>obj4 : Symbol(obj4, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 38, 3)) +>foo : Symbol(B.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 26, 16)) + + obj4.bar = "str"; +>obj4 : Symbol(obj4, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 38, 3)) +} + +// has multiple construct signature +interface CConstructor { +>CConstructor : Symbol(CConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 43, 1)) + + new (value: string): C1; +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 47, 9)) +>C1 : Symbol(C1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 50, 1)) + + new (value: number): C2; +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 48, 9)) +>C2 : Symbol(C2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 55, 1)) + + [Symbol.hasInstance](value: unknown): value is C1 | C2; +>[Symbol.hasInstance] : Symbol(CConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 48, 28)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 49, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 49, 25)) +>C1 : Symbol(C1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 50, 1)) +>C2 : Symbol(C2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 55, 1)) +} +interface C1 { +>C1 : Symbol(C1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 50, 1)) + + foo: string; +>foo : Symbol(C1.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 51, 14)) + + c: string; +>c : Symbol(C1.c, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 52, 16)) + + bar1: number; +>bar1 : Symbol(C1.bar1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 53, 14)) +} +interface C2 { +>C2 : Symbol(C2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 55, 1)) + + foo: string; +>foo : Symbol(C2.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 56, 14)) + + c: string; +>c : Symbol(C2.c, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 57, 16)) + + bar2: number; +>bar2 : Symbol(C2.bar2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 58, 14)) +} +declare var C: CConstructor; +>C : Symbol(C, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 61, 11)) +>CConstructor : Symbol(CConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 43, 1)) + +var obj5: C1 | A; +>obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) +>C1 : Symbol(C1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 50, 1)) +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + +if (obj5 instanceof C) { // narrowed to C1. +>obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) +>C : Symbol(C, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 61, 11)) + + obj5.foo; +>obj5.foo : Symbol(C1.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 51, 14)) +>obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) +>foo : Symbol(C1.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 51, 14)) + + obj5.c; +>obj5.c : Symbol(C1.c, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 52, 16)) +>obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) +>c : Symbol(C1.c, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 52, 16)) + + obj5.bar1; +>obj5.bar1 : Symbol(C1.bar1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 53, 14)) +>obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) +>bar1 : Symbol(C1.bar1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 53, 14)) + + obj5.bar2; +>obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) +} + +var obj6: any; +>obj6 : Symbol(obj6, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 71, 3)) + +if (obj6 instanceof C) { +>obj6 : Symbol(obj6, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 71, 3)) +>C : Symbol(C, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 61, 11)) + + obj6.foo; +>obj6.foo : Symbol(foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 51, 14), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 56, 14)) +>obj6 : Symbol(obj6, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 71, 3)) +>foo : Symbol(foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 51, 14), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 56, 14)) + + obj6.bar1; +>obj6 : Symbol(obj6, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 71, 3)) + + obj6.bar2; +>obj6 : Symbol(obj6, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 71, 3)) +} + +// with object type literal +interface D { +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + + foo: string; +>foo : Symbol(D.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 79, 13)) +} +declare var D: { +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + + new (): D; +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + + [Symbol.hasInstance](value: unknown): value is D; +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 83, 14)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 84, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 84, 25)) +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + +}; + +var obj7: D | string; +>obj7 : Symbol(obj7, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 87, 3)) +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + +if (obj7 instanceof D) { // narrowed to D. +>obj7 : Symbol(obj7, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 87, 3)) +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + + obj7.foo; +>obj7.foo : Symbol(D.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 79, 13)) +>obj7 : Symbol(obj7, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 87, 3)) +>foo : Symbol(D.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 79, 13)) + + obj7.bar; +>obj7 : Symbol(obj7, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 87, 3)) +} + +var obj8: any; +>obj8 : Symbol(obj8, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 93, 3)) + +if (obj8 instanceof D) { +>obj8 : Symbol(obj8, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 93, 3)) +>D : Symbol(D, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 76, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 82, 11)) + + obj8.foo; +>obj8.foo : Symbol(D.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 79, 13)) +>obj8 : Symbol(obj8, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 93, 3)) +>foo : Symbol(D.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 79, 13)) + + obj8.bar; +>obj8 : Symbol(obj8, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 93, 3)) +} + +// a construct signature that returns a union type +interface EConstructor { +>EConstructor : Symbol(EConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 97, 1)) + + new (): E1 | E2; +>E1 : Symbol(E1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 103, 1)) +>E2 : Symbol(E2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 107, 1)) + + [Symbol.hasInstance](value: unknown): value is E1 | E2; +>[Symbol.hasInstance] : Symbol(EConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 101, 20)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 102, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 102, 25)) +>E1 : Symbol(E1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 103, 1)) +>E2 : Symbol(E2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 107, 1)) +} +interface E1 { +>E1 : Symbol(E1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 103, 1)) + + foo: string; +>foo : Symbol(E1.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 104, 14)) + + bar1: number; +>bar1 : Symbol(E1.bar1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 105, 16)) +} +interface E2 { +>E2 : Symbol(E2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 107, 1)) + + foo: string; +>foo : Symbol(E2.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 108, 14)) + + bar2: number; +>bar2 : Symbol(E2.bar2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 109, 16)) +} +declare var E: EConstructor; +>E : Symbol(E, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 112, 11)) +>EConstructor : Symbol(EConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 97, 1)) + +var obj9: E1 | A; +>obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 114, 3)) +>E1 : Symbol(E1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 103, 1)) +>A : Symbol(A, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 3, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 7, 11)) + +if (obj9 instanceof E) { // narrowed to E1 +>obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 114, 3)) +>E : Symbol(E, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 112, 11)) + + obj9.foo; +>obj9.foo : Symbol(E1.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 104, 14)) +>obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 114, 3)) +>foo : Symbol(E1.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 104, 14)) + + obj9.bar1; +>obj9.bar1 : Symbol(E1.bar1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 105, 16)) +>obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 114, 3)) +>bar1 : Symbol(E1.bar1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 105, 16)) + + obj9.bar2; +>obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 114, 3)) +} + +var obj10: any; +>obj10 : Symbol(obj10, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 121, 3)) + +if (obj10 instanceof E) { +>obj10 : Symbol(obj10, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 121, 3)) +>E : Symbol(E, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 112, 11)) + + obj10.foo; +>obj10.foo : Symbol(foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 104, 14), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 108, 14)) +>obj10 : Symbol(obj10, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 121, 3)) +>foo : Symbol(foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 104, 14), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 108, 14)) + + obj10.bar1; +>obj10 : Symbol(obj10, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 121, 3)) + + obj10.bar2; +>obj10 : Symbol(obj10, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 121, 3)) +} + +// a construct signature that returns any +interface FConstructor { +>FConstructor : Symbol(FConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 126, 1)) + + new (): any; + [Symbol.hasInstance](value: unknown): value is any; +>[Symbol.hasInstance] : Symbol(FConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 130, 16)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 131, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 131, 25)) +} +interface F { +>F : Symbol(F, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 132, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 137, 11)) + + foo: string; +>foo : Symbol(F.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 133, 13)) + + bar: number; +>bar : Symbol(F.bar, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 134, 16)) +} +declare var F: FConstructor; +>F : Symbol(F, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 132, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 137, 11)) +>FConstructor : Symbol(FConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 126, 1)) + +var obj11: F | string; +>obj11 : Symbol(obj11, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 139, 3)) +>F : Symbol(F, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 132, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 137, 11)) + +if (obj11 instanceof F) { // can't type narrowing, construct signature returns any. +>obj11 : Symbol(obj11, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 139, 3)) +>F : Symbol(F, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 132, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 137, 11)) + + obj11.foo; +>obj11 : Symbol(obj11, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 139, 3)) + + obj11.bar; +>obj11 : Symbol(obj11, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 139, 3)) +} + +var obj12: any; +>obj12 : Symbol(obj12, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 145, 3)) + +if (obj12 instanceof F) { +>obj12 : Symbol(obj12, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 145, 3)) +>F : Symbol(F, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 132, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 137, 11)) + + obj12.foo; +>obj12 : Symbol(obj12, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 145, 3)) + + obj12.bar; +>obj12 : Symbol(obj12, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 145, 3)) +} + +// a type with a prototype, it overrides the construct signature +interface GConstructor { +>GConstructor : Symbol(GConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 149, 1)) + + prototype: G1; // high priority +>prototype : Symbol(GConstructor.prototype, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 152, 24)) +>G1 : Symbol(G1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 156, 1)) + + new (): G2; // low priority +>G2 : Symbol(G2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 159, 1)) + + [Symbol.hasInstance](value: unknown): value is G1; // overrides priority +>[Symbol.hasInstance] : Symbol(GConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 154, 15)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 155, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 155, 25)) +>G1 : Symbol(G1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 156, 1)) +} +interface G1 { +>G1 : Symbol(G1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 156, 1)) + + foo1: number; +>foo1 : Symbol(G1.foo1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 157, 14)) +} +interface G2 { +>G2 : Symbol(G2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 159, 1)) + + foo2: boolean; +>foo2 : Symbol(G2.foo2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 160, 14)) +} +declare var G: GConstructor; +>G : Symbol(G, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 163, 11)) +>GConstructor : Symbol(GConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 149, 1)) + +var obj13: G1 | G2; +>obj13 : Symbol(obj13, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 165, 3)) +>G1 : Symbol(G1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 156, 1)) +>G2 : Symbol(G2, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 159, 1)) + +if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. +>obj13 : Symbol(obj13, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 165, 3)) +>G : Symbol(G, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 163, 11)) + + obj13.foo1; +>obj13.foo1 : Symbol(G1.foo1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 157, 14)) +>obj13 : Symbol(obj13, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 165, 3)) +>foo1 : Symbol(G1.foo1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 157, 14)) + + obj13.foo2; +>obj13 : Symbol(obj13, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 165, 3)) +} + +var obj14: any; +>obj14 : Symbol(obj14, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 171, 3)) + +if (obj14 instanceof G) { +>obj14 : Symbol(obj14, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 171, 3)) +>G : Symbol(G, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 163, 11)) + + obj14.foo1; +>obj14.foo1 : Symbol(G1.foo1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 157, 14)) +>obj14 : Symbol(obj14, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 171, 3)) +>foo1 : Symbol(G1.foo1, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 157, 14)) + + obj14.foo2; +>obj14 : Symbol(obj14, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 171, 3)) +} + +// a type with a prototype that has any type +interface HConstructor { +>HConstructor : Symbol(HConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 175, 1)) + + prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`. +>prototype : Symbol(HConstructor.prototype, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 178, 24)) + + new (): H; // low priority +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) + + [Symbol.hasInstance](value: unknown): value is H; // overrides priority +>[Symbol.hasInstance] : Symbol(HConstructor[Symbol.hasInstance], Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 180, 14)) +>Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) +>hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 181, 25)) +>value : Symbol(value, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 181, 25)) +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) +} +interface H { +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) + + foo: number; +>foo : Symbol(H.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 183, 13)) +} +declare var H: HConstructor; +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) +>HConstructor : Symbol(HConstructor, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 175, 1)) + +var obj15: H | string; +>obj15 : Symbol(obj15, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 188, 3)) +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) + +if (obj15 instanceof H) { // narrowed to H. +>obj15 : Symbol(obj15, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 188, 3)) +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) + + obj15.foo; +>obj15.foo : Symbol(H.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 183, 13)) +>obj15 : Symbol(obj15, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 188, 3)) +>foo : Symbol(H.foo, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 183, 13)) + + obj15.bar; +>obj15 : Symbol(obj15, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 188, 3)) +} + +var obj16: any; +>obj16 : Symbol(obj16, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 194, 3)) + +if (obj16 instanceof H) { +>obj16 : Symbol(obj16, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 194, 3)) +>H : Symbol(H, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 182, 1), Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 186, 11)) + + obj16.foo1; +>obj16 : Symbol(obj16, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 194, 3)) + + obj16.foo2; +>obj16 : Symbol(obj16, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 194, 3)) +} + +var obj17: any; +>obj17 : Symbol(obj17, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 200, 3)) + +if (obj17 instanceof Object) { // can't narrow type from 'any' to 'Object' +>obj17 : Symbol(obj17, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 200, 3)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + obj17.foo1; +>obj17 : Symbol(obj17, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 200, 3)) + + obj17.foo2; +>obj17 : Symbol(obj17, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 200, 3)) +} + +var obj18: any; +>obj18 : Symbol(obj18, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 206, 3)) + +if (obj18 instanceof Function) { // can't narrow type from 'any' to 'Function' +>obj18 : Symbol(obj18, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 206, 3)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.decorators.d.ts, --, --)) + + obj18.foo1; +>obj18 : Symbol(obj18, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 206, 3)) + + obj18.foo2; +>obj18 : Symbol(obj18, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 206, 3)) +} + diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types new file mode 100644 index 0000000000000..aefd4d384b694 --- /dev/null +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types @@ -0,0 +1,572 @@ +//// [tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts] //// + +=== typeGuardsWithInstanceOfBySymbolHasInstance.ts === +interface AConstructor { + new (): A; + [Symbol.hasInstance](value: unknown): value is A; +>[Symbol.hasInstance] : (value: unknown) => value is A +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface A { + foo: string; +>foo : string +} +declare var A: AConstructor; +>A : AConstructor + +var obj1: A | string; +>obj1 : string | A + +if (obj1 instanceof A) { // narrowed to A. +>obj1 instanceof A : boolean +>obj1 : string | A +>A : AConstructor + + obj1.foo; +>obj1.foo : string +>obj1 : A +>foo : string + + obj1.bar; +>obj1.bar : any +>obj1 : A +>bar : any +} + +var obj2: any; +>obj2 : any + +if (obj2 instanceof A) { +>obj2 instanceof A : boolean +>obj2 : any +>A : AConstructor + + obj2.foo; +>obj2.foo : string +>obj2 : A +>foo : string + + obj2.bar; +>obj2.bar : any +>obj2 : A +>bar : any +} + +// a construct signature with generics +interface BConstructor { + new (): B; + [Symbol.hasInstance](value: unknown): value is B; +>[Symbol.hasInstance] : (value: unknown) => value is B +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface B { + foo: T; +>foo : T +} +declare var B: BConstructor; +>B : BConstructor + +var obj3: B | string; +>obj3 : string | B + +if (obj3 instanceof B) { // narrowed to B. +>obj3 instanceof B : boolean +>obj3 : string | B +>B : BConstructor + + obj3.foo = 1; +>obj3.foo = 1 : 1 +>obj3.foo : number +>obj3 : B +>foo : number +>1 : 1 + + obj3.foo = "str"; +>obj3.foo = "str" : "str" +>obj3.foo : number +>obj3 : B +>foo : number +>"str" : "str" + + obj3.bar = "str"; +>obj3.bar = "str" : "str" +>obj3.bar : any +>obj3 : B +>bar : any +>"str" : "str" +} + +var obj4: any; +>obj4 : any + +if (obj4 instanceof B) { +>obj4 instanceof B : boolean +>obj4 : any +>B : BConstructor + + obj4.foo = "str"; +>obj4.foo = "str" : "str" +>obj4.foo : any +>obj4 : B +>foo : any +>"str" : "str" + + obj4.foo = 1; +>obj4.foo = 1 : 1 +>obj4.foo : any +>obj4 : B +>foo : any +>1 : 1 + + obj4.bar = "str"; +>obj4.bar = "str" : "str" +>obj4.bar : any +>obj4 : B +>bar : any +>"str" : "str" +} + +// has multiple construct signature +interface CConstructor { + new (value: string): C1; +>value : string + + new (value: number): C2; +>value : number + + [Symbol.hasInstance](value: unknown): value is C1 | C2; +>[Symbol.hasInstance] : (value: unknown) => value is C1 | C2 +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface C1 { + foo: string; +>foo : string + + c: string; +>c : string + + bar1: number; +>bar1 : number +} +interface C2 { + foo: string; +>foo : string + + c: string; +>c : string + + bar2: number; +>bar2 : number +} +declare var C: CConstructor; +>C : CConstructor + +var obj5: C1 | A; +>obj5 : A | C1 + +if (obj5 instanceof C) { // narrowed to C1. +>obj5 instanceof C : boolean +>obj5 : A | C1 +>C : CConstructor + + obj5.foo; +>obj5.foo : string +>obj5 : C1 +>foo : string + + obj5.c; +>obj5.c : string +>obj5 : C1 +>c : string + + obj5.bar1; +>obj5.bar1 : number +>obj5 : C1 +>bar1 : number + + obj5.bar2; +>obj5.bar2 : any +>obj5 : C1 +>bar2 : any +} + +var obj6: any; +>obj6 : any + +if (obj6 instanceof C) { +>obj6 instanceof C : boolean +>obj6 : any +>C : CConstructor + + obj6.foo; +>obj6.foo : string +>obj6 : C1 | C2 +>foo : string + + obj6.bar1; +>obj6.bar1 : any +>obj6 : C1 | C2 +>bar1 : any + + obj6.bar2; +>obj6.bar2 : any +>obj6 : C1 | C2 +>bar2 : any +} + +// with object type literal +interface D { + foo: string; +>foo : string +} +declare var D: { +>D : { new (): D; [Symbol.hasInstance](value: unknown): value is D; } + + new (): D; + [Symbol.hasInstance](value: unknown): value is D; +>[Symbol.hasInstance] : (value: unknown) => value is D +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown + +}; + +var obj7: D | string; +>obj7 : string | D + +if (obj7 instanceof D) { // narrowed to D. +>obj7 instanceof D : boolean +>obj7 : string | D +>D : { new (): D; [Symbol.hasInstance](value: unknown): value is D; } + + obj7.foo; +>obj7.foo : string +>obj7 : D +>foo : string + + obj7.bar; +>obj7.bar : any +>obj7 : D +>bar : any +} + +var obj8: any; +>obj8 : any + +if (obj8 instanceof D) { +>obj8 instanceof D : boolean +>obj8 : any +>D : { new (): D; [Symbol.hasInstance](value: unknown): value is D; } + + obj8.foo; +>obj8.foo : string +>obj8 : D +>foo : string + + obj8.bar; +>obj8.bar : any +>obj8 : D +>bar : any +} + +// a construct signature that returns a union type +interface EConstructor { + new (): E1 | E2; + [Symbol.hasInstance](value: unknown): value is E1 | E2; +>[Symbol.hasInstance] : (value: unknown) => value is E1 | E2 +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface E1 { + foo: string; +>foo : string + + bar1: number; +>bar1 : number +} +interface E2 { + foo: string; +>foo : string + + bar2: number; +>bar2 : number +} +declare var E: EConstructor; +>E : EConstructor + +var obj9: E1 | A; +>obj9 : A | E1 + +if (obj9 instanceof E) { // narrowed to E1 +>obj9 instanceof E : boolean +>obj9 : A | E1 +>E : EConstructor + + obj9.foo; +>obj9.foo : string +>obj9 : E1 +>foo : string + + obj9.bar1; +>obj9.bar1 : number +>obj9 : E1 +>bar1 : number + + obj9.bar2; +>obj9.bar2 : any +>obj9 : E1 +>bar2 : any +} + +var obj10: any; +>obj10 : any + +if (obj10 instanceof E) { +>obj10 instanceof E : boolean +>obj10 : any +>E : EConstructor + + obj10.foo; +>obj10.foo : string +>obj10 : E1 | E2 +>foo : string + + obj10.bar1; +>obj10.bar1 : any +>obj10 : E1 | E2 +>bar1 : any + + obj10.bar2; +>obj10.bar2 : any +>obj10 : E1 | E2 +>bar2 : any +} + +// a construct signature that returns any +interface FConstructor { + new (): any; + [Symbol.hasInstance](value: unknown): value is any; +>[Symbol.hasInstance] : (value: unknown) => value is any +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface F { + foo: string; +>foo : string + + bar: number; +>bar : number +} +declare var F: FConstructor; +>F : FConstructor + +var obj11: F | string; +>obj11 : string | F + +if (obj11 instanceof F) { // can't type narrowing, construct signature returns any. +>obj11 instanceof F : boolean +>obj11 : string | F +>F : FConstructor + + obj11.foo; +>obj11.foo : any +>obj11 : string | F +>foo : any + + obj11.bar; +>obj11.bar : any +>obj11 : string | F +>bar : any +} + +var obj12: any; +>obj12 : any + +if (obj12 instanceof F) { +>obj12 instanceof F : boolean +>obj12 : any +>F : FConstructor + + obj12.foo; +>obj12.foo : any +>obj12 : any +>foo : any + + obj12.bar; +>obj12.bar : any +>obj12 : any +>bar : any +} + +// a type with a prototype, it overrides the construct signature +interface GConstructor { + prototype: G1; // high priority +>prototype : G1 + + new (): G2; // low priority + [Symbol.hasInstance](value: unknown): value is G1; // overrides priority +>[Symbol.hasInstance] : (value: unknown) => value is G1 +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface G1 { + foo1: number; +>foo1 : number +} +interface G2 { + foo2: boolean; +>foo2 : boolean +} +declare var G: GConstructor; +>G : GConstructor + +var obj13: G1 | G2; +>obj13 : G1 | G2 + +if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. +>obj13 instanceof G : boolean +>obj13 : G1 | G2 +>G : GConstructor + + obj13.foo1; +>obj13.foo1 : number +>obj13 : G1 +>foo1 : number + + obj13.foo2; +>obj13.foo2 : any +>obj13 : G1 +>foo2 : any +} + +var obj14: any; +>obj14 : any + +if (obj14 instanceof G) { +>obj14 instanceof G : boolean +>obj14 : any +>G : GConstructor + + obj14.foo1; +>obj14.foo1 : number +>obj14 : G1 +>foo1 : number + + obj14.foo2; +>obj14.foo2 : any +>obj14 : G1 +>foo2 : any +} + +// a type with a prototype that has any type +interface HConstructor { + prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`. +>prototype : any + + new (): H; // low priority + [Symbol.hasInstance](value: unknown): value is H; // overrides priority +>[Symbol.hasInstance] : (value: unknown) => value is H +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>value : unknown +} +interface H { + foo: number; +>foo : number +} +declare var H: HConstructor; +>H : HConstructor + +var obj15: H | string; +>obj15 : string | H + +if (obj15 instanceof H) { // narrowed to H. +>obj15 instanceof H : boolean +>obj15 : string | H +>H : HConstructor + + obj15.foo; +>obj15.foo : number +>obj15 : H +>foo : number + + obj15.bar; +>obj15.bar : any +>obj15 : H +>bar : any +} + +var obj16: any; +>obj16 : any + +if (obj16 instanceof H) { +>obj16 instanceof H : boolean +>obj16 : any +>H : HConstructor + + obj16.foo1; +>obj16.foo1 : any +>obj16 : H +>foo1 : any + + obj16.foo2; +>obj16.foo2 : any +>obj16 : H +>foo2 : any +} + +var obj17: any; +>obj17 : any + +if (obj17 instanceof Object) { // can't narrow type from 'any' to 'Object' +>obj17 instanceof Object : boolean +>obj17 : any +>Object : ObjectConstructor + + obj17.foo1; +>obj17.foo1 : any +>obj17 : any +>foo1 : any + + obj17.foo2; +>obj17.foo2 : any +>obj17 : any +>foo2 : any +} + +var obj18: any; +>obj18 : any + +if (obj18 instanceof Function) { // can't narrow type from 'any' to 'Function' +>obj18 instanceof Function : boolean +>obj18 : any +>Function : FunctionConstructor + + obj18.foo1; +>obj18.foo1 : any +>obj18 : any +>foo1 : any + + obj18.foo2; +>obj18.foo2 : any +>obj18 : any +>foo2 : any +} + diff --git a/tests/cases/compiler/controlFlowInstanceofWithSymbolHasInstance.ts b/tests/cases/compiler/controlFlowInstanceofWithSymbolHasInstance.ts new file mode 100644 index 0000000000000..83b38fce9df27 --- /dev/null +++ b/tests/cases/compiler/controlFlowInstanceofWithSymbolHasInstance.ts @@ -0,0 +1,118 @@ +// @target: es6 +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @strictNullChecks: true + +interface PromiseConstructor { + [Symbol.hasInstance](value: any): value is Promise; +} + +interface SetConstructor { + [Symbol.hasInstance](value: any): value is Set; +} + +function f1(s: Set | Set) { + s = new Set(); + s; // Set + if (s instanceof Set) { + s; // Set + } + s; // Set + s.add(42); +} + +function f2(s: Set | Set) { + s = new Set(); + s; // Set + if (s instanceof Promise) { + s; // Set & Promise + } + s; // Set + s.add(42); +} + +function f3(s: Set | Set) { + s; // Set | Set + if (s instanceof Set) { + s; // Set | Set + } + else { + s; // never + } +} + +function f4(s: Set | Set) { + s = new Set(); + s; // Set + if (s instanceof Set) { + s; // Set + } + else { + s; // never + } +} + +// More tests + +class A { + a: string; + static [Symbol.hasInstance](this: T, value: unknown): value is ( + T extends (abstract new (...args: any) => infer U) ? U : + never + ) { + return Function.prototype[Symbol.hasInstance].call(this, value); + } +} +class B extends A { b: string } +class C extends A { c: string } + +function foo(x: A | undefined) { + x; // A | undefined + if (x instanceof B || x instanceof C) { + x; // B | C + } + x; // A | undefined + if (x instanceof B && x instanceof C) { + x; // B & C + } + x; // A | undefined + if (!x) { + return; + } + x; // A + if (x instanceof B) { + x; // B + if (x instanceof C) { + x; // B & C + } + else { + x; // B + } + x; // B + } + else { + x; // A + } + x; // A +} + +// X is neither assignable to Y nor a subtype of Y +// Y is assignable to X, but not a subtype of X + +interface X { + x?: string; +} + +class Y { + y: string; +} + +function goo(x: X) { + x; + if (x instanceof Y) { + x.y; + } + x; +} + diff --git a/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts new file mode 100644 index 0000000000000..d608292502dbf --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts @@ -0,0 +1,57 @@ +// @target: es2015 +// @lib: es2015 +class C { + foo() { } +} + +var x: any; + +// invalid left operand +// the left operand is required to be of type Any, an object type, or a type parameter type +var a1: number; +var a2: boolean; +var a3: string; +var a4: void; + +var ra1 = a1 instanceof x; +var ra2 = a2 instanceof x; +var ra3 = a3 instanceof x; +var ra4 = a4 instanceof x; +var ra5 = 0 instanceof x; +var ra6 = true instanceof x; +var ra7 = '' instanceof x; +var ra8 = null instanceof x; +var ra9 = undefined instanceof x; + +// invalid right operand +// the right operand to be of type Any or a subtype of the 'Function' interface type +var b1: number; +var b2: boolean; +var b3: string; +var b4: void; +var o1: {}; +var o2: Object; +var o3: C; + +var rb1 = x instanceof b1; +var rb2 = x instanceof b2; +var rb3 = x instanceof b3; +var rb4 = x instanceof b4; +var rb5 = x instanceof 0; +var rb6 = x instanceof true; +var rb7 = x instanceof ''; +var rb8 = x instanceof o1; +var rb9 = x instanceof o2; +var rb10 = x instanceof o3; + +// both operands are invalid +var rc1 = '' instanceof {}; + +// @@hasInstance restricts LHS +var o4: {[Symbol.hasInstance](value: { x: number }): boolean;}; +var o5: { y: string }; +var ra10 = o5 instanceof o4; + +// invalid @@hasInstance method return type on RHS +var o6: {[Symbol.hasInstance](value: unknown): number;}; +var rb11 = x instanceof o6; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts new file mode 100644 index 0000000000000..2b33ccb330c52 --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts @@ -0,0 +1,118 @@ +// @target: es2015 +// @lib: es2015 + +interface Point { x: number, y: number } +interface Point3D { x: number, y: number, z: number } +interface Point3D2 extends Point { z: number } +interface Line { start: Point, end: Point } + +declare var rhs0: { [Symbol.hasInstance](value: unknown): boolean; }; +declare var rhs1: { [Symbol.hasInstance](value: any): boolean; }; +declare var rhs2: { [Symbol.hasInstance](value: any): value is Point; }; +declare var rhs3: { [Symbol.hasInstance](value: Point | Line): value is Point; }; +declare var rhs4: { [Symbol.hasInstance](value: Point | Line): value is Line; }; +declare var rhs5: { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; }; +declare var rhs6: { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; }; + +declare class Rhs7 { static [Symbol.hasInstance](value: unknown): boolean; } +declare class Rhs8 { static [Symbol.hasInstance](value: any): boolean; } +declare class Rhs9 { static [Symbol.hasInstance](value: any): value is Point; } +declare class Rhs10 { static [Symbol.hasInstance](value: Point | Line): value is Point; } +declare class Rhs11 { static [Symbol.hasInstance](value: Point | Line): value is Line; } +declare class Rhs12 { static [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +declare class Rhs13 { static [Symbol.hasInstance](value: Point3D | Line): value is Point3D; } + +declare var lhs0: any; +declare var lhs1: object; +declare var lhs2: Point | Point3D | Line; +declare var lhs3: Point3D | Line; +declare var lhs4: Point | Point3D2 | Line; + +lhs0 instanceof rhs0 && lhs0; +lhs0 instanceof rhs1 && lhs0; +lhs0 instanceof rhs2 && lhs0; +lhs0 instanceof rhs3 && lhs0; +lhs0 instanceof rhs4 && lhs0; +lhs0 instanceof rhs5 && lhs0; +lhs0 instanceof rhs6 && lhs0; +lhs0 instanceof Rhs7 && lhs0; +lhs0 instanceof Rhs8 && lhs0; +lhs0 instanceof Rhs9 && lhs0; +lhs0 instanceof Rhs10 && lhs0; +lhs0 instanceof Rhs11 && lhs0; +lhs0 instanceof Rhs12 && lhs0; +lhs0 instanceof Rhs13 && lhs0; + +lhs1 instanceof rhs0 && lhs1; +lhs1 instanceof rhs1 && lhs1; +lhs1 instanceof rhs2 && lhs1; +lhs1 instanceof Rhs7 && lhs1; +lhs1 instanceof Rhs8 && lhs1; +lhs1 instanceof Rhs9 && lhs1; + +lhs2 instanceof rhs0 && lhs2; +lhs2 instanceof rhs1 && lhs2; +lhs2 instanceof rhs2 && lhs2; +lhs2 instanceof rhs3 && lhs2; +lhs2 instanceof rhs4 && lhs2; +lhs2 instanceof rhs5 && lhs2; +lhs2 instanceof Rhs7 && lhs2; +lhs2 instanceof Rhs8 && lhs2; +lhs2 instanceof Rhs9 && lhs2; +lhs2 instanceof Rhs10 && lhs2; +lhs2 instanceof Rhs11 && lhs2; +lhs2 instanceof Rhs12 && lhs2; + +lhs3 instanceof rhs0 && lhs3; +lhs3 instanceof rhs1 && lhs3; +lhs3 instanceof rhs2 && lhs3; +lhs3 instanceof rhs3 && lhs3; +lhs3 instanceof rhs4 && lhs3; +lhs3 instanceof rhs5 && lhs3; +lhs3 instanceof rhs6 && lhs3; +lhs3 instanceof Rhs7 && lhs3; +lhs3 instanceof Rhs8 && lhs3; +lhs3 instanceof Rhs9 && lhs3; +lhs3 instanceof Rhs10 && lhs3; +lhs3 instanceof Rhs11 && lhs3; +lhs3 instanceof Rhs12 && lhs3; +lhs3 instanceof Rhs13 && lhs3; + +lhs4 instanceof rhs0 && lhs4; +lhs4 instanceof rhs1 && lhs4; +lhs4 instanceof rhs2 && lhs4; +lhs4 instanceof rhs3 && lhs4; +lhs4 instanceof rhs4 && lhs4; +lhs4 instanceof rhs5 && lhs4; +lhs4 instanceof Rhs7 && lhs4; +lhs4 instanceof Rhs8 && lhs4; +lhs4 instanceof Rhs9 && lhs4; +lhs4 instanceof Rhs10 && lhs4; +lhs4 instanceof Rhs11 && lhs4; +lhs4 instanceof Rhs12 && lhs4; + +declare class A { + #x: number; + + // approximation of `getInstanceType` behavior, with one caveat: the checker versions unions the return types of + // all construct signatures, but we have no way of extracting individual construct signatures from a type. + static [Symbol.hasInstance](this: T, value: unknown): value is ( + T extends globalThis.Function ? + T extends { readonly prototype: infer U } ? + boolean extends (U extends never ? true : false) ? // <- tests whether 'U' is 'any' + T extends (abstract new (...args: any) => infer V) ? V : {} : + U : + never : + never + ); +} + +declare class B extends A { #y: number; } + +declare const obj: unknown; +if (obj instanceof A) { + obj; // A +} +if (obj instanceof B) { + obj; // B +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts index 0817954c35c5c..39febe097edc0 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts @@ -59,7 +59,7 @@ interface C2 { declare var C: CConstructor; var obj5: C1 | A; -if (obj5 instanceof C) { // narrowed to C1|C2. +if (obj5 instanceof C) { // narrowed to C1. obj5.foo; obj5.c; obj5.bar1; @@ -106,7 +106,7 @@ interface E2 { declare var E: EConstructor; var obj9: E1 | A; -if (obj9 instanceof E) { // narrowed to E1 | E2 +if (obj9 instanceof E) { // narrowed to E1 obj9.foo; obj9.bar1; obj9.bar2; diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts new file mode 100644 index 0000000000000..d47a87a483548 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts @@ -0,0 +1,213 @@ +// @lib: esnext + +interface AConstructor { + new (): A; + [Symbol.hasInstance](value: unknown): value is A; +} +interface A { + foo: string; +} +declare var A: AConstructor; + +var obj1: A | string; +if (obj1 instanceof A) { // narrowed to A. + obj1.foo; + obj1.bar; +} + +var obj2: any; +if (obj2 instanceof A) { + obj2.foo; + obj2.bar; +} + +// a construct signature with generics +interface BConstructor { + new (): B; + [Symbol.hasInstance](value: unknown): value is B; +} +interface B { + foo: T; +} +declare var B: BConstructor; + +var obj3: B | string; +if (obj3 instanceof B) { // narrowed to B. + obj3.foo = 1; + obj3.foo = "str"; + obj3.bar = "str"; +} + +var obj4: any; +if (obj4 instanceof B) { + obj4.foo = "str"; + obj4.foo = 1; + obj4.bar = "str"; +} + +// has multiple construct signature +interface CConstructor { + new (value: string): C1; + new (value: number): C2; + [Symbol.hasInstance](value: unknown): value is C1 | C2; +} +interface C1 { + foo: string; + c: string; + bar1: number; +} +interface C2 { + foo: string; + c: string; + bar2: number; +} +declare var C: CConstructor; + +var obj5: C1 | A; +if (obj5 instanceof C) { // narrowed to C1. + obj5.foo; + obj5.c; + obj5.bar1; + obj5.bar2; +} + +var obj6: any; +if (obj6 instanceof C) { + obj6.foo; + obj6.bar1; + obj6.bar2; +} + +// with object type literal +interface D { + foo: string; +} +declare var D: { + new (): D; + [Symbol.hasInstance](value: unknown): value is D; +}; + +var obj7: D | string; +if (obj7 instanceof D) { // narrowed to D. + obj7.foo; + obj7.bar; +} + +var obj8: any; +if (obj8 instanceof D) { + obj8.foo; + obj8.bar; +} + +// a construct signature that returns a union type +interface EConstructor { + new (): E1 | E2; + [Symbol.hasInstance](value: unknown): value is E1 | E2; +} +interface E1 { + foo: string; + bar1: number; +} +interface E2 { + foo: string; + bar2: number; +} +declare var E: EConstructor; + +var obj9: E1 | A; +if (obj9 instanceof E) { // narrowed to E1 + obj9.foo; + obj9.bar1; + obj9.bar2; +} + +var obj10: any; +if (obj10 instanceof E) { + obj10.foo; + obj10.bar1; + obj10.bar2; +} + +// a construct signature that returns any +interface FConstructor { + new (): any; + [Symbol.hasInstance](value: unknown): value is any; +} +interface F { + foo: string; + bar: number; +} +declare var F: FConstructor; + +var obj11: F | string; +if (obj11 instanceof F) { // can't type narrowing, construct signature returns any. + obj11.foo; + obj11.bar; +} + +var obj12: any; +if (obj12 instanceof F) { + obj12.foo; + obj12.bar; +} + +// a type with a prototype, it overrides the construct signature +interface GConstructor { + prototype: G1; // high priority + new (): G2; // low priority + [Symbol.hasInstance](value: unknown): value is G1; // overrides priority +} +interface G1 { + foo1: number; +} +interface G2 { + foo2: boolean; +} +declare var G: GConstructor; + +var obj13: G1 | G2; +if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property. + obj13.foo1; + obj13.foo2; +} + +var obj14: any; +if (obj14 instanceof G) { + obj14.foo1; + obj14.foo2; +} + +// a type with a prototype that has any type +interface HConstructor { + prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`. + new (): H; // low priority + [Symbol.hasInstance](value: unknown): value is H; // overrides priority +} +interface H { + foo: number; +} +declare var H: HConstructor; + +var obj15: H | string; +if (obj15 instanceof H) { // narrowed to H. + obj15.foo; + obj15.bar; +} + +var obj16: any; +if (obj16 instanceof H) { + obj16.foo1; + obj16.foo2; +} + +var obj17: any; +if (obj17 instanceof Object) { // can't narrow type from 'any' to 'Object' + obj17.foo1; + obj17.foo2; +} + +var obj18: any; +if (obj18 instanceof Function) { // can't narrow type from 'any' to 'Function' + obj18.foo1; + obj18.foo2; +} diff --git a/tests/cases/fourslash/goToDefinitionInstanceof1.ts b/tests/cases/fourslash/goToDefinitionInstanceof1.ts new file mode 100644 index 0000000000000..39c0d55eaeaa9 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionInstanceof1.ts @@ -0,0 +1,8 @@ +/// + +//// class /*end*/ C { +//// } +//// declare var obj: any; +//// obj [|/*start*/instanceof|] C; + +verify.baselineGoToDefinition("start"); diff --git a/tests/cases/fourslash/goToDefinitionInstanceof2.ts b/tests/cases/fourslash/goToDefinitionInstanceof2.ts new file mode 100644 index 0000000000000..6edc4a9d1de8a --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionInstanceof2.ts @@ -0,0 +1,11 @@ +/// + +// @lib: esnext +// @filename: /main.ts +//// class C { +//// static /*end*/[Symbol.hasInstance](value: unknown): boolean { return true; } +//// } +//// declare var obj: any; +//// obj [|/*start*/instanceof|] C; + +verify.baselineGoToDefinition("start");