From 69f59daef2edbcd78833156c5f368fe0505f262e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 17 Jul 2023 13:48:41 -0400 Subject: [PATCH 01/12] [WIP] Support custom 'Symbol.hasInstance' methods when checking/narrowing 'instanceof' --- src/compiler/checker.ts | 119 ++++++++++++++++++++++++--- src/compiler/diagnosticMessages.json | 12 +++ src/compiler/types.ts | 2 +- src/compiler/utilitiesPublic.ts | 1 + 4 files changed, 122 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f1324425367bb..81bc589078f34 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -704,6 +704,7 @@ import { isStringOrNumericLiteralLike, isSuperCall, isSuperProperty, + isSyntheticExpression, isTaggedTemplateExpression, isTemplateSpan, isThisContainerOrFunctionBlock, @@ -27463,6 +27464,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type; } const rightType = getTypeOfExpression(expr.right); + // if rightType is 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 customHasInstanceMethodType = getCustomSymbolHasInstanceMethodOfObjectType(rightType); + if (customHasInstanceMethodType) { + const syntheticCall = createSyntheticHasInstanceMethodCall(left, expr.right, type, customHasInstanceMethodType); + const signature = getEffectsSignature(syntheticCall); + const predicate = signature && getTypePredicateOfSignature(signature); + if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) { + return narrowTypeByTypePredicate(type, predicate, syntheticCall, assumeTrue); + } + } if (!isTypeDerivedFrom(rightType, globalFunctionType)) { return type; } @@ -27560,8 +27573,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function narrowTypeByTypePredicate(type: Type, predicate: TypePredicate, callExpression: CallExpression, assumeTrue: boolean): Type { // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function' if (predicate.type && !(isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType))) { - const predicateArgument = getTypePredicateArgument(predicate, callExpression); + let predicateArgument = getTypePredicateArgument(predicate, callExpression); if (predicateArgument) { + // If the predicate argument is synthetic and is the first argument of a synthetic call to + // `[Symbol.hasInstance]`, replace the synthetic predicate argument with the actual argument from + // the original `instanceof` expression which is stored as the synthetic argument's `parent`. + if (isSyntheticExpression(predicateArgument) && + predicate.parameterIndex === 0 && + isSyntheticHasInstanceMethodCall(callExpression)) { + Debug.assertNode(predicateArgument.parent, isExpression); + predicateArgument = predicateArgument.parent; + } if (isMatchingReference(reference, predicateArgument)) { return getNarrowedType(type, predicate.type, assumeTrue, /*checkDerived*/ false); } @@ -33153,7 +33175,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount); } - function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessage?: DiagnosticMessage): Signature { + function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessageCallback?: () => DiagnosticMessage | undefined): Signature { const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); @@ -33266,6 +33288,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { chain = chainDiagnosticMessages(chain, Diagnostics.The_last_overload_gave_the_following_error); chain = chainDiagnosticMessages(chain, Diagnostics.No_overload_matches_this_call); } + const headMessage = headMessageCallback?.(); if (headMessage) { chain = chainDiagnosticMessages(chain, headMessage); } @@ -33311,6 +33334,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let chain = chainDiagnosticMessages( map(diags, createDiagnosticMessageChainFromDiagnostic), Diagnostics.No_overload_matches_this_call); + const headMessage = headMessageCallback?.(); if (headMessage) { chain = chainDiagnosticMessages(chain, headMessage); } @@ -33330,18 +33354,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else if (candidateForArgumentArityError) { - diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessage)); + diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessageCallback?.())); } else if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessage); + checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessageCallback?.()); } else { const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); if (signaturesWithCorrectTypeArgumentArity.length === 0) { - diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!, headMessage)); + diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!, headMessageCallback?.())); } else { - diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args, headMessage)); + diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args, headMessageCallback?.())); } } } @@ -33689,7 +33713,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveErrorCall(node); } - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); + // 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. + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags, () => isSyntheticHasInstanceMethodCall(node) ? + 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 : + undefined); } function isGenericFunctionReturningFunction(signature: Signature) { @@ -34072,7 +34101,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveErrorCall(node); } - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None, headMessage); + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None, () => headMessage); } function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature { @@ -36445,6 +36474,52 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return (symbol.flags & SymbolFlags.ConstEnum) !== 0; } + /** + * Get the type of the `[Symbol.hasInstance]` method of an object type, but only if it is not the + * `[Symbol.hasInstance]` method inherited from the global `Function` type. + */ + function getCustomSymbolHasInstanceMethodOfObjectType(type: Type) { + const hasInstancePropertyName = getPropertyNameForKnownSymbolName("hasInstance"); + const hasInstanceProperty = getPropertyOfObjectType(type, hasInstancePropertyName); + if (hasInstanceProperty && hasInstanceProperty !== getPropertyOfObjectType(globalFunctionType, hasInstancePropertyName)) { + const hasInstancePropertyType = getTypeOfSymbol(hasInstanceProperty); + if (hasInstancePropertyType && getSignaturesOfType(hasInstancePropertyType, SignatureKind.Call).length !== 0) { + return hasInstancePropertyType; + } + } + } + + /** + * Creates a synthetic `CallExpression` that reinterprets `left instanceof right` as `right[Symbol.hasInstance](left)` + * per the `InstanceofOperator` algorithm in the ECMAScript specification. + * @param left The left-hand expression of `instanceof` + * @param right The right-hand expression of `instanceof` + * @param leftType The type of the left-hand expression of `instanceof`. + * @param hasInstanceMethodType The type of the `[Symbol.hasInstance]` method of the right-hand expression of `instanceof`. + */ + function createSyntheticHasInstanceMethodCall(left: Expression, right: Expression, leftType: Type, hasInstanceMethodType: Type) { + const syntheticExpression = createSyntheticExpression(right, hasInstanceMethodType); + const syntheticArgument = createSyntheticExpression(left, leftType); + const syntheticCall = parseNodeFactory.createCallExpression(syntheticExpression, /*typeArguments*/ undefined, [syntheticArgument]); + setParent(syntheticCall, left.parent); + setTextRange(syntheticCall, left.parent); + return syntheticCall; + } + + /** + * Tests whether a `CallExpression` is a synthetic call to a `[Symbol.hasInstance]` method as would be produced by + * {@link createSyntheticHasInstanceMethodCall}. + */ + function isSyntheticHasInstanceMethodCall(node: CallExpression) { + return isSyntheticExpression(node.expression) && + node.arguments.length === 1 && + isSyntheticExpression(node.arguments[0]) && + isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === SyntaxKind.InstanceOfKeyword && + node.parent.right === node.expression.parent && + node.parent.left === node.arguments[0].parent; + } + function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; @@ -36458,9 +36533,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { allTypesAssignableToKind(leftType, TypeFlags.Primitive)) { 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); + if (!isTypeAny(rightType)) { + // 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 customHasInstanceMethodType = getCustomSymbolHasInstanceMethodOfObjectType(rightType); + if (customHasInstanceMethodType) { + // If rightType has a `[Symbol.hasInstance]` method that is not the default [Symbol.hasInstance]() method on `Function`, check + // that left is assignable to the first parameter. + const syntheticCall = createSyntheticHasInstanceMethodCall(left, right, leftType, customHasInstanceMethodType); + const returnType = getReturnTypeOfSignature(getResolvedSignature(syntheticCall)); + + // Also verify that the return type of the `[Symbol.hasInstance]` method is assignable to `boolean`. The spec + // will 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); + } + // NOTE: do not raise error if right is unknown as related error was already reported + if (!(customHasInstanceMethodType || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { + // Do not indicate that `[Symbol.hasInstance]` is a valid option if it's not known to be present on `SymbolConstructor`. + const globalESSymbolConstructorSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); + const hasInstanceProp = globalESSymbolConstructorSymbol && getMembersOfSymbol(globalESSymbolConstructorSymbol).get(getPropertyNameForKnownSymbolName("hasInstance")); + const message = hasInstanceProp ? + Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_of_an_object_type_with_a_Symbol_hasInstance_method_or_of_a_type_assignable_to_the_Function_interface_type : + Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type; + error(right, message); + } } return booleanType; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e15199127169c..42d2a4f836a9e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3659,6 +3659,18 @@ "category": "Error", "code": 2854 }, + "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": 2855 + }, + "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": 2856 + }, + "The right-hand side of an 'instanceof' expression must be either of type 'any', of an object type with a '[Symbol.hasInstance]()' method, or of a type assignable to the 'Function' interface type.": { + "category": "Error", + "code": 2857 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 63ca3980ca64a..a65d58bb74bf9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2485,7 +2485,7 @@ export interface YieldExpression extends Expression { readonly expression?: Expression; } -export interface SyntheticExpression extends Expression { +export interface SyntheticExpression extends LeftHandSideExpression { readonly kind: SyntaxKind.SyntheticExpression; readonly isSpread: boolean; readonly type: Type; diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 62be656474719..756fab0e46d87 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1978,6 +1978,7 @@ function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean { case SyntaxKind.MetaProperty: case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression case SyntaxKind.MissingDeclaration: + case SyntaxKind.SyntheticExpression: // synthetic expressions are only used by the checker to substitute specific types for expression positions, so their precedence does not matter. return true; default: return false; From 161d1f16bfd6057dc8747c0925e9373717d9f83e Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 17 Jul 2023 18:04:02 -0400 Subject: [PATCH 02/12] Add tests for instanceof and narrowing --- src/compiler/checker.ts | 64 ++- src/compiler/diagnosticMessages.json | 2 +- src/compiler/types.ts | 5 + .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- ...ratorWithInvalidOperands.es2015.errors.txt | 132 +++++ ...nceofOperatorWithInvalidOperands.es2015.js | 107 ++++ ...OperatorWithInvalidOperands.es2015.symbols | 177 +++++++ ...ofOperatorWithInvalidOperands.es2015.types | 205 ++++++++ ...ceofOperatorWithRHSHasSymbolHasInstance.js | 126 +++++ ...peratorWithRHSHasSymbolHasInstance.symbols | 418 ++++++++++++++++ ...fOperatorWithRHSHasSymbolHasInstance.types | 462 ++++++++++++++++++ ...nceofOperatorWithInvalidOperands.es2015.ts | 57 +++ ...ceofOperatorWithRHSHasSymbolHasInstance.ts | 77 +++ 14 files changed, 1811 insertions(+), 25 deletions(-) create mode 100644 tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt create mode 100644 tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.js create mode 100644 tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.symbols create mode 100644 tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.types create mode 100644 tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js create mode 100644 tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols create mode 100644 tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types create mode 100644 tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithInvalidOperands.es2015.ts create mode 100644 tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 81bc589078f34..3698ece5fa42c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -381,6 +381,7 @@ import { HasIllegalModifiers, HasInitializer, hasInitializer, + HasInstanceMethodType, hasJSDocNodes, hasJSDocParameterTags, hasJsonModuleEmitEnabled, @@ -2186,6 +2187,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var potentialReflectCollisions: Node[] = []; var potentialUnusedRenamedBindingElementsInTypes: BindingElement[] = []; var awaitedTypeStack: number[] = []; + var hasGlobalSymbolHasInstanceProperty: boolean | undefined; var diagnostics = createDiagnosticCollection(); var suggestionDiagnostics = createDiagnosticCollection(); @@ -27467,9 +27469,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // if rightType is 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 customHasInstanceMethodType = getCustomSymbolHasInstanceMethodOfObjectType(rightType); - if (customHasInstanceMethodType) { - const syntheticCall = createSyntheticHasInstanceMethodCall(left, expr.right, type, customHasInstanceMethodType); + const hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(rightType); + if (hasInstanceMethodType) { + const syntheticCall = createSyntheticHasInstanceMethodCall(left, expr.right, type, hasInstanceMethodType); const signature = getEffectsSignature(syntheticCall); const predicate = signature && getTypePredicateOfSignature(signature); if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) { @@ -36475,13 +36477,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } /** - * Get the type of the `[Symbol.hasInstance]` method of an object type, but only if it is not the - * `[Symbol.hasInstance]` method inherited from the global `Function` type. + * Get the type of the `[Symbol.hasInstance]` method of an object type. */ - function getCustomSymbolHasInstanceMethodOfObjectType(type: Type) { + function getSymbolHasInstanceMethodOfObjectType(type: Type) { const hasInstancePropertyName = getPropertyNameForKnownSymbolName("hasInstance"); const hasInstanceProperty = getPropertyOfObjectType(type, hasInstancePropertyName); - if (hasInstanceProperty && hasInstanceProperty !== getPropertyOfObjectType(globalFunctionType, hasInstancePropertyName)) { + if (hasInstanceProperty) { const hasInstancePropertyType = getTypeOfSymbol(hasInstanceProperty); if (hasInstancePropertyType && getSignaturesOfType(hasInstancePropertyType, SignatureKind.Call).length !== 0) { return hasInstancePropertyType; @@ -36537,24 +36538,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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 customHasInstanceMethodType = getCustomSymbolHasInstanceMethodOfObjectType(rightType); - if (customHasInstanceMethodType) { - // If rightType has a `[Symbol.hasInstance]` method that is not the default [Symbol.hasInstance]() method on `Function`, check - // that left is assignable to the first parameter. - const syntheticCall = createSyntheticHasInstanceMethodCall(left, right, leftType, customHasInstanceMethodType); - const returnType = getReturnTypeOfSignature(getResolvedSignature(syntheticCall)); - - // Also verify that the return type of the `[Symbol.hasInstance]` method is assignable to `boolean`. The spec - // will 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); + const hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(rightType); + if (hasInstanceMethodType) { + // avoid a complex check for every `instanceof` when the `[Symbol.hasInstance]` method has a single + // call signature that neither restricts nor narrows (via type predicate) the LHS value, e.g. + // `(value: unknown) => boolean`. + const cache = hasInstanceMethodType as HasInstanceMethodType; + if (cache.hasSimpleUnrestrictedSingleCallSignature === undefined) { + const signature = getSingleCallSignature(hasInstanceMethodType); + cache.hasSimpleUnrestrictedSingleCallSignature = !!signature && signature.parameters.length === 1 && + !!(getTypeOfSymbol(signature.parameters[0]).flags & TypeFlags.AnyOrUnknown) && + !!signature.resolvedReturnType && + !!(signature.resolvedReturnType.flags & TypeFlags.Boolean); + } + if (!cache.hasSimpleUnrestrictedSingleCallSignature) { + // 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)1. The call to + // `getResolvedSignature`, below, will check that leftType is assignable to the type of the first + // parameter. + const syntheticCall = createSyntheticHasInstanceMethodCall(left, right, leftType, hasInstanceMethodType); + const returnType = getReturnTypeOfSignature(getResolvedSignature(syntheticCall)); + + // 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); + } } // NOTE: do not raise error if right is unknown as related error was already reported - if (!(customHasInstanceMethodType || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { + if (!(hasInstanceMethodType || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { // Do not indicate that `[Symbol.hasInstance]` is a valid option if it's not known to be present on `SymbolConstructor`. - const globalESSymbolConstructorSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); - const hasInstanceProp = globalESSymbolConstructorSymbol && getMembersOfSymbol(globalESSymbolConstructorSymbol).get(getPropertyNameForKnownSymbolName("hasInstance")); - const message = hasInstanceProp ? - Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_of_an_object_type_with_a_Symbol_hasInstance_method_or_of_a_type_assignable_to_the_Function_interface_type : + if (hasGlobalSymbolHasInstanceProperty === undefined) { + const globalESSymbolConstructorSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); + hasGlobalSymbolHasInstanceProperty = !!globalESSymbolConstructorSymbol && getMembersOfSymbol(globalESSymbolConstructorSymbol).has("hasInstance" as __String); + } + + const message = hasGlobalSymbolHasInstanceProperty ? + Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_an_object_type_with_a_Symbol_hasInstance_method_or_a_type_assignable_to_the_Function_interface_type : Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type; error(right, message); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 42d2a4f836a9e..34d0c48e6dcb7 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3667,7 +3667,7 @@ "category": "Error", "code": 2856 }, - "The right-hand side of an 'instanceof' expression must be either of type 'any', of an object type with a '[Symbol.hasInstance]()' method, or of a type assignable to the 'Function' interface type.": { + "The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type.": { "category": "Error", "code": 2857 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a65d58bb74bf9..f686ae1c47082 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6564,6 +6564,11 @@ export interface PromiseOrAwaitableType extends ObjectType, UnionType { awaitedTypeOfType?: Type; } +/** @internal */ +export interface HasInstanceMethodType extends Type { + hasSimpleUnrestrictedSingleCallSignature?: boolean; +} + /** @internal */ export interface SyntheticDefaultModuleType extends Type { syntheticType?: Type; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 82625637de7ca..0df80ceefc8dd 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5139,7 +5139,7 @@ declare namespace ts { readonly asteriskToken?: AsteriskToken; readonly expression?: Expression; } - interface SyntheticExpression extends Expression { + interface SyntheticExpression extends LeftHandSideExpression { readonly kind: SyntaxKind.SyntheticExpression; readonly isSpread: boolean; readonly type: Type; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a396cc8d4ad7a..54dc656a5a0ab 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1086,7 +1086,7 @@ declare namespace ts { readonly asteriskToken?: AsteriskToken; readonly expression?: Expression; } - interface SyntheticExpression extends Expression { + interface SyntheticExpression extends LeftHandSideExpression { readonly kind: SyntaxKind.SyntheticExpression; readonly isSpread: boolean; readonly type: Type; diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt new file mode 100644 index 0000000000000..620dcbfc0e512 --- /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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(35,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(36,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(37,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(38,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(39,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(40,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(41,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(42,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(43,25): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(51,12): error TS2855: 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 TS2856: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb2 = x instanceof b2; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb3 = x instanceof b3; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb4 = x instanceof b4; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb5 = x instanceof 0; + ~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb6 = x instanceof true; + ~~~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb7 = x instanceof ''; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb8 = x instanceof o1; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb9 = x instanceof o2; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + var rb10 = x instanceof o3; + ~~ +!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + + // 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. + + // @@hasInstance restricts LHS + var o4: {[Symbol.hasInstance](value: { x: number }): boolean;}; + var o5: { y: string }; + var ra10 = o5 instanceof o4; + ~~ +!!! error TS2855: 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 TS2855: Argument of type '{ y: string; }' is not assignable to parameter of type '{ x: number; }'. +!!! error TS2855: 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 TS2856: 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..56be1475bc4ab --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js @@ -0,0 +1,126 @@ +//// [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 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; + +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; + + +//// [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; diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols new file mode 100644 index 0000000000000..bf14553c83ff2 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols @@ -0,0 +1,418 @@ +//// [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 Line { start: Point, end: Point } +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>start : Symbol(Line.start, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 16)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>end : Symbol(Line.end, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 30)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +declare var rhs0: { [Symbol.hasInstance](value: unknown): boolean; }; +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) +>[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 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, 4, 41)) + +declare var rhs1: { [Symbol.hasInstance](value: any): boolean; }; +>rhs1 : Symbol(rhs1, 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 rhs2: { [Symbol.hasInstance](value: any): value is Point; }; +>rhs2 : Symbol(rhs2, 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)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 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, 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)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 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, 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, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 41)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) + +declare var rhs5: { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; }; +>rhs5 : Symbol(rhs5, 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)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 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, 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)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 41)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) + +declare class Rhs7 { static [Symbol.hasInstance](value: unknown): boolean; } +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) +>[Symbol.hasInstance] : Symbol(Rhs7[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 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, 12, 49)) + +declare class Rhs8 { static [Symbol.hasInstance](value: any): boolean; } +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) +>[Symbol.hasInstance] : Symbol(Rhs8[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 Rhs9 { static [Symbol.hasInstance](value: any): value is Point; } +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) +>[Symbol.hasInstance] : Symbol(Rhs9[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)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 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, 14, 79)) +>[Symbol.hasInstance] : Symbol(Rhs10[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 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, 15, 50)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 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, 15, 89)) +>[Symbol.hasInstance] : Symbol(Rhs11[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, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 50)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) + +declare class Rhs12 { static [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; } +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) +>[Symbol.hasInstance] : Symbol(Rhs12[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)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 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, 17, 101)) +>[Symbol.hasInstance] : Symbol(Rhs13[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)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 50)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) + +declare var lhs0: any; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +declare var lhs1: object; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +declare var lhs2: Point | Point3D | Line; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) + +declare var lhs3: Point3D | Line; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) + +lhs0 instanceof rhs0 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof rhs1 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof rhs2 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof rhs3 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof rhs4 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof rhs5 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof rhs6 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs7 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs8 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs9 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs10 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 79)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs11 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 89)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs12 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs0 instanceof Rhs13 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 101)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) + +lhs1 instanceof rhs0 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs1 instanceof rhs1 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs1 instanceof rhs2 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs1 instanceof Rhs7 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs1 instanceof Rhs8 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs1 instanceof Rhs9 && lhs1; +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +lhs2 instanceof rhs0 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof rhs1 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof rhs2 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof rhs3 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof rhs4 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof rhs5 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof Rhs7 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof Rhs8 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof Rhs9 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof Rhs10 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 79)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof Rhs11 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 89)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs2 instanceof Rhs12 && lhs2; +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) +>lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) + +lhs3 instanceof rhs0 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs1 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs2 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs3 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs4 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs5 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof rhs6 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs7 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs8 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs9 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs10 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 79)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs11 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 89)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs12 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + +lhs3 instanceof Rhs13 && lhs3; +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 101)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) + diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types new file mode 100644 index 0000000000000..0091ac0ed5608 --- /dev/null +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types @@ -0,0 +1,462 @@ +//// [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 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 + +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 | Point3D +>lhs2 instanceof rhs2 : boolean +>lhs2 : Point | Point3D | Line +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs2 : Point | Point3D + +lhs2 instanceof rhs3 && lhs2; +>lhs2 instanceof rhs3 && lhs2 : Point | Point3D +>lhs2 instanceof rhs3 : boolean +>lhs2 : Point | Point3D | Line +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>lhs2 : Point | Point3D + +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 | Point3D +>lhs2 instanceof Rhs9 : boolean +>lhs2 : Point | Point3D | Line +>Rhs9 : typeof Rhs9 +>lhs2 : Point | Point3D + +lhs2 instanceof Rhs10 && lhs2; +>lhs2 instanceof Rhs10 && lhs2 : Point | Point3D +>lhs2 instanceof Rhs10 : boolean +>lhs2 : Point | Point3D | Line +>Rhs10 : typeof Rhs10 +>lhs2 : Point | Point3D + +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 +>lhs3 instanceof rhs2 : boolean +>lhs3 : Point3D | Line +>rhs2 : { [Symbol.hasInstance](value: any): value is Point; } +>lhs3 : Point3D + +lhs3 instanceof rhs3 && lhs3; +>lhs3 instanceof rhs3 && lhs3 : Point3D +>lhs3 instanceof rhs3 : boolean +>lhs3 : Point3D | Line +>rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } +>lhs3 : Point3D + +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 +>lhs3 instanceof Rhs9 : boolean +>lhs3 : Point3D | Line +>Rhs9 : typeof Rhs9 +>lhs3 : Point3D + +lhs3 instanceof Rhs10 && lhs3; +>lhs3 instanceof Rhs10 && lhs3 : Point3D +>lhs3 instanceof Rhs10 : boolean +>lhs3 : Point3D | Line +>Rhs10 : typeof Rhs10 +>lhs3 : Point3D + +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 + 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..a93f51a38dea0 --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts @@ -0,0 +1,77 @@ +// @target: es2015 +// @lib: es2015 + +interface Point { x: number, y: number } +interface Point3D { x: number, y: number, 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; + +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; From 6a4f838e705bf0cffde30e62bf93f570f8398353 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 17 Jul 2023 18:10:30 -0400 Subject: [PATCH 03/12] Accept baseline, fix lint --- src/compiler/checker.ts | 4 ++-- tests/baselines/reference/symbolType1.errors.txt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3698ece5fa42c..f4c1001f28d09 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36541,7 +36541,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(rightType); if (hasInstanceMethodType) { // avoid a complex check for every `instanceof` when the `[Symbol.hasInstance]` method has a single - // call signature that neither restricts nor narrows (via type predicate) the LHS value, e.g. + // call signature that neither restricts nor narrows (via type predicate) the LHS value, e.g. // `(value: unknown) => boolean`. const cache = hasInstanceMethodType as HasInstanceMethodType; if (cache.hasSimpleUnrestrictedSingleCallSignature === undefined) { @@ -36558,7 +36558,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // parameter. const syntheticCall = createSyntheticHasInstanceMethodCall(left, right, leftType, hasInstanceMethodType); const returnType = getReturnTypeOfSignature(getResolvedSignature(syntheticCall)); - + // 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. diff --git a/tests/baselines/reference/symbolType1.errors.txt b/tests/baselines/reference/symbolType1.errors.txt index cde9160e0b2fb..ab65833ad7375 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +symbolType1.ts(4,19): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. ==== 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. (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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. \ No newline at end of file From af6bb551a162d7df4375e4ef604c1b7676aee565 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Sat, 12 Aug 2023 01:01:12 -0400 Subject: [PATCH 04/12] Check derived types when using type predicates with instanceof/hasInstance --- src/compiler/checker.ts | 62 ++-- src/compiler/factory/nodeFactory.ts | 3 +- src/compiler/types.ts | 3 +- ...lowInstanceofWithSymbolHasInstance.symbols | 293 ++++++++++++++++++ ...lFlowInstanceofWithSymbolHasInstance.types | 293 ++++++++++++++++++ ...trolFlowInstanceofWithSymbolHasInstance.ts | 118 +++++++ ...ceofOperatorWithRHSHasSymbolHasInstance.ts | 15 + ...GuardsWithInstanceOfBySymbolHasInstance.ts | 211 +++++++++++++ 8 files changed, 963 insertions(+), 35 deletions(-) create mode 100644 tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.symbols create mode 100644 tests/baselines/reference/controlFlowInstanceofWithSymbolHasInstance.types create mode 100644 tests/cases/compiler/controlFlowInstanceofWithSymbolHasInstance.ts create mode 100644 tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f4c1001f28d09..d71441c02b9c7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27465,23 +27465,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return type; } - const rightType = getTypeOfExpression(expr.right); - // if rightType is 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 hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(rightType); - if (hasInstanceMethodType) { - const syntheticCall = createSyntheticHasInstanceMethodCall(left, expr.right, type, hasInstanceMethodType); - const signature = getEffectsSignature(syntheticCall); - const predicate = signature && getTypePredicateOfSignature(signature); - if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) { - return narrowTypeByTypePredicate(type, predicate, syntheticCall, assumeTrue); - } - } - if (!isTypeDerivedFrom(rightType, globalFunctionType)) { - return type; - } - const instanceType = mapType(rightType, getInstanceType); + const right = expr.right; + const rightType = getTypeOfExpression(right); + const instanceType = mapType(rightType, t => getInstanceType(t, left, type, right)); // Don't narrow from `any` if the target type is exactly `Object` or `Function`, and narrow // in the false branch only if the target is a non-empty object type. if (isTypeAny(type) && (instanceType === globalObjectType || instanceType === globalFunctionType) || @@ -27491,7 +27477,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getNarrowedType(type, instanceType, assumeTrue, /*checkDerived*/ true); } - function getInstanceType(constructorType: Type) { + function getInstanceType(constructorType: Type, left: Expression, leftType: Type, right: Expression) { + // if rightType is 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 hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(constructorType); + if (hasInstanceMethodType) { + const syntheticCall = createSyntheticHasInstanceMethodCall(left, leftType, right, constructorType, hasInstanceMethodType); + const signature = getEffectsSignature(syntheticCall); + const predicate = signature && getTypePredicateOfSignature(signature); + if (predicate && predicate.kind == TypePredicateKind.Identifier && predicate.parameterIndex == 0) { + return predicate.type; + } + if (!isTypeDerivedFrom(constructorType, globalFunctionType)) { + return leftType; + } + } const prototypePropertyType = getTypeOfPropertyOfType(constructorType, "prototype" as __String); if (prototypePropertyType && !isTypeAny(prototypePropertyType)) { return prototypePropertyType; @@ -27575,17 +27576,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function narrowTypeByTypePredicate(type: Type, predicate: TypePredicate, callExpression: CallExpression, assumeTrue: boolean): Type { // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function' if (predicate.type && !(isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType))) { - let predicateArgument = getTypePredicateArgument(predicate, callExpression); + const predicateArgument = getTypePredicateArgument(predicate, callExpression); if (predicateArgument) { - // If the predicate argument is synthetic and is the first argument of a synthetic call to - // `[Symbol.hasInstance]`, replace the synthetic predicate argument with the actual argument from - // the original `instanceof` expression which is stored as the synthetic argument's `parent`. - if (isSyntheticExpression(predicateArgument) && - predicate.parameterIndex === 0 && - isSyntheticHasInstanceMethodCall(callExpression)) { - Debug.assertNode(predicateArgument.parent, isExpression); - predicateArgument = predicateArgument.parent; - } if (isMatchingReference(reference, predicateArgument)) { return getNarrowedType(type, predicate.type, assumeTrue, /*checkDerived*/ false); } @@ -32891,11 +32883,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isAccessExpression(callee)) { return callee.expression; } + if (isSyntheticExpression(callee)) { + return callee.thisArgument; + } } } - function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { - const result = parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource); + function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember, thisArgument?: LeftHandSideExpression) { + const result = parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource, thisArgument); setTextRange(result, parent); setParent(result, parent); return result; @@ -36498,8 +36493,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @param leftType The type of the left-hand expression of `instanceof`. * @param hasInstanceMethodType The type of the `[Symbol.hasInstance]` method of the right-hand expression of `instanceof`. */ - function createSyntheticHasInstanceMethodCall(left: Expression, right: Expression, leftType: Type, hasInstanceMethodType: Type) { - const syntheticExpression = createSyntheticExpression(right, hasInstanceMethodType); + function createSyntheticHasInstanceMethodCall(left: Expression, leftType: Type, right: Expression, rightType: Type, hasInstanceMethodType: Type) { + const thisArgument = createSyntheticExpression(right, rightType); + const syntheticExpression = createSyntheticExpression(right, hasInstanceMethodType, /*isSpread*/ false, /*tupleNameSource*/ undefined, thisArgument); const syntheticArgument = createSyntheticExpression(left, leftType); const syntheticCall = parseNodeFactory.createCallExpression(syntheticExpression, /*typeArguments*/ undefined, [syntheticArgument]); setParent(syntheticCall, left.parent); @@ -36556,7 +36552,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // must check the expression as if it were a call to `right[Symbol.hasInstance](left)1. The call to // `getResolvedSignature`, below, will check that leftType is assignable to the type of the first // parameter. - const syntheticCall = createSyntheticHasInstanceMethodCall(left, right, leftType, hasInstanceMethodType); + const syntheticCall = createSyntheticHasInstanceMethodCall(left, leftType, right, rightType, hasInstanceMethodType); const returnType = getReturnTypeOfSignature(getResolvedSignature(syntheticCall)); // We also verify that the return type of the `[Symbol.hasInstance]` method is assignable to diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 9dd48e0437efe..41b6f34c904b3 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -6133,11 +6133,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // // @api - function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { + function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember, thisArgument?: LeftHandSideExpression) { const node = createBaseNode(SyntaxKind.SyntheticExpression); node.type = type; node.isSpread = isSpread; node.tupleNameSource = tupleNameSource; + node.thisArgument = thisArgument; return node; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f686ae1c47082..4ce4377d48340 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2490,6 +2490,7 @@ export interface SyntheticExpression extends LeftHandSideExpression { readonly isSpread: boolean; readonly type: Type; readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; + readonly thisArgument?: LeftHandSideExpression; } // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression @@ -8833,7 +8834,7 @@ export interface NodeFactory { // // Synthetic Nodes // - /** @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember): SyntheticExpression; + /** @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember, thisArgument?: LeftHandSideExpression): SyntheticExpression; /** @internal */ createSyntaxList(children: Node[]): SyntaxList; // 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/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/instanceofOperatorWithRHSHasSymbolHasInstance.ts b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts index a93f51a38dea0..76067db4cf1d3 100644 --- a/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts +++ b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts @@ -3,6 +3,7 @@ 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; }; @@ -25,6 +26,7 @@ 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; @@ -75,3 +77,16 @@ 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; diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts new file mode 100644 index 0000000000000..9c2cfbac077ae --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts @@ -0,0 +1,211 @@ +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|C2. + 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 | E2 + 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; +} From 6a83254c041a13f2616b4d6ce704ab0210845fbc Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 14 Aug 2023 14:54:34 -0400 Subject: [PATCH 05/12] Small tweaks, lint fixes, and baseline updates --- src/compiler/checker.ts | 5 +- .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + ...ceofOperatorWithRHSHasSymbolHasInstance.js | 60 +- ...peratorWithRHSHasSymbolHasInstance.symbols | 555 ++++++++++------- ...fOperatorWithRHSHasSymbolHasInstance.types | 181 +++++- ...thInstanceOfBySymbolHasInstance.errors.txt | 289 +++++++++ ...GuardsWithInstanceOfBySymbolHasInstance.js | 314 ++++++++++ ...sWithInstanceOfBySymbolHasInstance.symbols | 583 ++++++++++++++++++ ...rdsWithInstanceOfBySymbolHasInstance.types | 572 +++++++++++++++++ ...ceofOperatorWithRHSHasSymbolHasInstance.ts | 26 + ...GuardsWithInstanceOfBySymbolHasInstance.ts | 2 + 12 files changed, 2363 insertions(+), 226 deletions(-) create mode 100644 tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt create mode 100644 tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js create mode 100644 tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols create mode 100644 tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d71441c02b9c7..1ae3e8baf4a86 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27467,6 +27467,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const right = expr.right; const rightType = getTypeOfExpression(right); + if (!isTypeDerivedFrom(rightType, globalObjectType)) { + return type; + } const instanceType = mapType(rightType, t => getInstanceType(t, left, type, right)); // Don't narrow from `any` if the target type is exactly `Object` or `Function`, and narrow // in the false branch only if the target is a non-empty object type. @@ -27486,7 +27489,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const syntheticCall = createSyntheticHasInstanceMethodCall(left, leftType, right, constructorType, hasInstanceMethodType); const signature = getEffectsSignature(syntheticCall); const predicate = signature && getTypePredicateOfSignature(signature); - if (predicate && predicate.kind == TypePredicateKind.Identifier && predicate.parameterIndex == 0) { + if (predicate && predicate.kind === TypePredicateKind.Identifier && predicate.parameterIndex === 0) { return predicate.type; } if (!isTypeDerivedFrom(constructorType, globalFunctionType)) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0df80ceefc8dd..a9dd8b64574f1 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5144,6 +5144,7 @@ declare namespace ts { readonly isSpread: boolean; readonly type: Type; readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; + readonly thisArgument?: LeftHandSideExpression; } type ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken; type MultiplicativeOperator = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 54dc656a5a0ab..c685ca4533b27 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1091,6 +1091,7 @@ declare namespace ts { readonly isSpread: boolean; readonly type: Type; readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; + readonly thisArgument?: LeftHandSideExpression; } type ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken; type MultiplicativeOperator = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken; diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js index 56be1475bc4ab..0d4984e43e0a0 100644 --- a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js @@ -3,6 +3,7 @@ //// [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; }; @@ -25,6 +26,7 @@ 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; @@ -75,7 +77,45 @@ 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; @@ -124,3 +164,21 @@ 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 index bf14553c83ff2..e2d111f8772be 100644 --- a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols @@ -12,407 +12,546 @@ interface Point3D { x: number, y: number, z: number } >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, 1, 53)) ->start : Symbol(Line.start, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 16)) +>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, 2, 30)) +>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, 4, 11)) ->[Symbol.hasInstance] : Symbol([Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 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, 4, 41)) - -declare var rhs1: { [Symbol.hasInstance](value: any): boolean; }; ->rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) +>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 rhs2: { [Symbol.hasInstance](value: any): value is Point; }; ->rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) +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)) ->value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 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, 7, 11)) +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)) ->Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) >value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 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, 8, 11)) +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, 1, 53)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) >value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 41)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) -declare var rhs5: { [Symbol.hasInstance](value: Point | Point3D | Line): value is Point3D; }; ->rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) +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)) ->Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) >value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 41)) ->Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) -declare var rhs6: { [Symbol.hasInstance](value: Point3D | Line): value is Point3D; }; ->rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) +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, 1, 53)) +>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, 10, 85)) ->[Symbol.hasInstance] : Symbol(Rhs7[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 20)) +>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, 12, 49)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 49)) declare class Rhs8 { static [Symbol.hasInstance](value: any): boolean; } ->Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) ->[Symbol.hasInstance] : Symbol(Rhs8[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 20)) +>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, 13, 49)) +>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, 13, 72)) ->[Symbol.hasInstance] : Symbol(Rhs9[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 20)) +>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, 14, 49)) ->value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 49)) +>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, 14, 79)) ->[Symbol.hasInstance] : Symbol(Rhs10[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 21)) +>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, 15, 50)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 50)) >Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) ->value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 50)) +>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, 15, 89)) ->[Symbol.hasInstance] : Symbol(Rhs11[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 21)) +>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, 16, 50)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 50)) >Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) ->value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 50)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>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, 16, 88)) ->[Symbol.hasInstance] : Symbol(Rhs12[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 21)) +>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, 17, 50)) +>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, 1, 53)) ->value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 50)) +>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, 17, 101)) ->[Symbol.hasInstance] : Symbol(Rhs13[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 21)) +>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, 18, 50)) +>value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 19, 50)) >Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) ->value : Symbol(value, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 18, 50)) +>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, 20, 11)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) declare var lhs1: object; ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) declare var lhs2: Point | Point3D | Line; ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 1, 53)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) declare var lhs3: Point3D | Line; ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 24, 11)) >Point3D : Symbol(Point3D, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 40)) ->Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 1, 53)) +>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, 20, 11)) ->rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 79)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 89)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 20, 11)) ->Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 101)) ->lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 20, 11)) +>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, 21, 11)) ->rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>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, 21, 11)) ->rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>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, 21, 11)) ->rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>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, 21, 11)) ->Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>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, 21, 11)) ->Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>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, 21, 11)) ->Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) ->lhs1 : Symbol(lhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>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, 22, 11)) ->rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 79)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 89)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 22, 11)) ->Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) ->lhs2 : Symbol(lhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 22, 11)) +>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, 23, 11)) ->rhs0 : Symbol(rhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 4, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->rhs1 : Symbol(rhs1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 5, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->rhs2 : Symbol(rhs2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 6, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->rhs3 : Symbol(rhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 7, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->rhs4 : Symbol(rhs4, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 8, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->rhs5 : Symbol(rhs5, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 9, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->rhs6 : Symbol(rhs6, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 11)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs7 : Symbol(Rhs7, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 10, 85)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs8 : Symbol(Rhs8, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 12, 76)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs9 : Symbol(Rhs9, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 13, 72)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs10 : Symbol(Rhs10, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 14, 79)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs11 : Symbol(Rhs11, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 15, 89)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs12 : Symbol(Rhs12, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 16, 88)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) +>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, 23, 11)) ->Rhs13 : Symbol(Rhs13, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 17, 101)) ->lhs3 : Symbol(lhs3, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 23, 11)) - +>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 index 0091ac0ed5608..fc8be58916595 100644 --- a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types @@ -10,6 +10,9 @@ interface Point3D { x: number, y: number, z: number } >y : number >z : number +interface Point3D2 extends Point { z: number } +>z : number + interface Line { start: Point, end: Point } >start : Point >end : Point @@ -138,6 +141,9 @@ declare var 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 @@ -293,18 +299,18 @@ lhs2 instanceof rhs1 && lhs2; >lhs2 : Point | Point3D | Line lhs2 instanceof rhs2 && lhs2; ->lhs2 instanceof rhs2 && lhs2 : Point | Point3D +>lhs2 instanceof rhs2 && lhs2 : Point >lhs2 instanceof rhs2 : boolean >lhs2 : Point | Point3D | Line >rhs2 : { [Symbol.hasInstance](value: any): value is Point; } ->lhs2 : Point | Point3D +>lhs2 : Point lhs2 instanceof rhs3 && lhs2; ->lhs2 instanceof rhs3 && lhs2 : Point | Point3D +>lhs2 instanceof rhs3 && lhs2 : Point >lhs2 instanceof rhs3 : boolean >lhs2 : Point | Point3D | Line >rhs3 : { [Symbol.hasInstance](value: Point | Line): value is Point; } ->lhs2 : Point | Point3D +>lhs2 : Point lhs2 instanceof rhs4 && lhs2; >lhs2 instanceof rhs4 && lhs2 : Line @@ -335,18 +341,18 @@ lhs2 instanceof Rhs8 && lhs2; >lhs2 : Point | Point3D | Line lhs2 instanceof Rhs9 && lhs2; ->lhs2 instanceof Rhs9 && lhs2 : Point | Point3D +>lhs2 instanceof Rhs9 && lhs2 : Point >lhs2 instanceof Rhs9 : boolean >lhs2 : Point | Point3D | Line >Rhs9 : typeof Rhs9 ->lhs2 : Point | Point3D +>lhs2 : Point lhs2 instanceof Rhs10 && lhs2; ->lhs2 instanceof Rhs10 && lhs2 : Point | Point3D +>lhs2 instanceof Rhs10 && lhs2 : Point >lhs2 instanceof Rhs10 : boolean >lhs2 : Point | Point3D | Line >Rhs10 : typeof Rhs10 ->lhs2 : Point | Point3D +>lhs2 : Point lhs2 instanceof Rhs11 && lhs2; >lhs2 instanceof Rhs11 && lhs2 : Line @@ -377,18 +383,18 @@ lhs3 instanceof rhs1 && lhs3; >lhs3 : Point3D | Line lhs3 instanceof rhs2 && lhs3; ->lhs3 instanceof rhs2 && lhs3 : Point3D +>lhs3 instanceof rhs2 && lhs3 : (Point3D | Line) & Point >lhs3 instanceof rhs2 : boolean >lhs3 : Point3D | Line >rhs2 : { [Symbol.hasInstance](value: any): value is Point; } ->lhs3 : Point3D +>lhs3 : (Point3D | Line) & Point lhs3 instanceof rhs3 && lhs3; ->lhs3 instanceof rhs3 && lhs3 : Point3D +>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 +>lhs3 : (Point3D | Line) & Point lhs3 instanceof rhs4 && lhs3; >lhs3 instanceof rhs4 && lhs3 : Line @@ -426,18 +432,18 @@ lhs3 instanceof Rhs8 && lhs3; >lhs3 : Point3D | Line lhs3 instanceof Rhs9 && lhs3; ->lhs3 instanceof Rhs9 && lhs3 : Point3D +>lhs3 instanceof Rhs9 && lhs3 : (Point3D | Line) & Point >lhs3 instanceof Rhs9 : boolean >lhs3 : Point3D | Line >Rhs9 : typeof Rhs9 ->lhs3 : Point3D +>lhs3 : (Point3D | Line) & Point lhs3 instanceof Rhs10 && lhs3; ->lhs3 instanceof Rhs10 && lhs3 : Point3D +>lhs3 instanceof Rhs10 && lhs3 : (Point3D | Line) & Point >lhs3 instanceof Rhs10 : boolean >lhs3 : Point3D | Line >Rhs10 : typeof Rhs10 ->lhs3 : Point3D +>lhs3 : (Point3D | Line) & Point lhs3 instanceof Rhs11 && lhs3; >lhs3 instanceof Rhs11 && lhs3 : Line @@ -460,3 +466,146 @@ lhs3 instanceof Rhs13 && lhs3; >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/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt new file mode 100644 index 0000000000000..0b87da6891ad9 --- /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|C2. + 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 | E2 + 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..7e3de3d6e7be5 --- /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|C2. + 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 | E2 + 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|C2. + 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 | E2 + 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..87fe09bfee5e3 --- /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|C2. +>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 | E2 +>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..7c82a54446c2d --- /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|C2. +>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 | E2 +>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/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts index 76067db4cf1d3..2b33ccb330c52 100644 --- a/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts +++ b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts @@ -90,3 +90,29 @@ 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/typeGuardsWithInstanceOfBySymbolHasInstance.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts index 9c2cfbac077ae..00f45c472422c 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts @@ -1,3 +1,5 @@ +// @lib: esnext + interface AConstructor { new (): A; [Symbol.hasInstance](value: unknown): value is A; From 511c9553a307722961f7ce44d6cb4197e6ed321b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 18 Sep 2023 16:23:17 -0400 Subject: [PATCH 06/12] Add go-to-definition support on 'instanceof' keyword --- src/compiler/checker.ts | 15 ++++++++++++++ src/services/goToDefinition.ts | 2 +- .../goToDefinitionInstanceof1.baseline.jsonc | 19 ++++++++++++++++++ .../goToDefinitionInstanceof2.baseline.jsonc | 20 +++++++++++++++++++ .../fourslash/goToDefinitionInstanceof1.ts | 8 ++++++++ .../fourslash/goToDefinitionInstanceof2.ts | 11 ++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/goToDefinitionInstanceof1.baseline.jsonc create mode 100644 tests/baselines/reference/goToDefinitionInstanceof2.baseline.jsonc create mode 100644 tests/cases/fourslash/goToDefinitionInstanceof1.ts create mode 100644 tests/cases/fourslash/goToDefinitionInstanceof2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ae3e8baf4a86..dc56984488b1e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -45992,6 +45992,21 @@ 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); + // const hasInstancePropertyName = getPropertyNameForKnownSymbolName("hasInstance"); + // const hasInstanceProperty = getPropertyOfObjectType(type, hasInstancePropertyName); + // if (hasInstanceProperty) { + // const hasInstancePropertyType = getTypeOfSymbol(hasInstanceProperty); + // if (hasInstancePropertyType && getSignaturesOfType(hasInstancePropertyType, SignatureKind.Call).length !== 0) { + // return hasInstanceProperty; + // } + // } + return hasInstanceMethodType?.symbol ?? type.symbol; + } + return undefined; case SyntaxKind.MetaProperty: return checkExpression(node as Expression).symbol; case SyntaxKind.JsxNamespacedName: diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 3688a688c53d8..258ef5eb667dd 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -101,7 +101,7 @@ import { TypeChecker, TypeFlags, TypeReference, - unescapeLeadingUnderscores, + unescapeLeadingUnderscores } from "./_namespaces/ts"; /** @internal */ 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/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"); From 4b0eafc43304ddc48b338a213ba9a1f5911554e0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 19 Sep 2023 15:18:16 -0400 Subject: [PATCH 07/12] Fix format --- src/compiler/checker.ts | 7 ++++--- src/services/goToDefinition.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9e949526124b8..82b37f8e6f2b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34334,9 +34334,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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. - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags, () => isSyntheticHasInstanceMethodCall(node) ? - 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 : - undefined); + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags, () => + isSyntheticHasInstanceMethodCall(node) ? + 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 : + undefined); } function isGenericFunctionReturningFunction(signature: Signature) { diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 97d2f6736bfa0..e622ed105d443 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -102,7 +102,7 @@ import { TypeChecker, TypeFlags, TypeReference, - unescapeLeadingUnderscores + unescapeLeadingUnderscores, } from "./_namespaces/ts"; /** @internal */ From befa293a880c91110ad57b6d34e924363e8ace85 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 19 Sep 2023 16:12:17 -0400 Subject: [PATCH 08/12] Address PR feedback --- src/compiler/checker.ts | 32 +++++--------- src/compiler/diagnosticMessages.json | 2 +- ...ratorWithInvalidOperands.es2015.errors.txt | 44 +++++++++---------- .../reference/symbolType1.errors.txt | 8 ++-- ...nstanceOfByConstructorSignature.errors.txt | 4 +- ...rdsWithInstanceOfByConstructorSignature.js | 8 ++-- ...thInstanceOfByConstructorSignature.symbols | 4 +- ...WithInstanceOfByConstructorSignature.types | 4 +- ...thInstanceOfBySymbolHasInstance.errors.txt | 4 +- ...GuardsWithInstanceOfBySymbolHasInstance.js | 8 ++-- ...sWithInstanceOfBySymbolHasInstance.symbols | 4 +- ...rdsWithInstanceOfBySymbolHasInstance.types | 4 +- ...rdsWithInstanceOfByConstructorSignature.ts | 4 +- ...GuardsWithInstanceOfBySymbolHasInstance.ts | 4 +- 14 files changed, 62 insertions(+), 72 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 82b37f8e6f2b4..fe43196e1d862 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33791,7 +33791,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount); } - function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessageCallback?: () => DiagnosticMessage | undefined): Signature { + function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessage?: DiagnosticMessage | undefined): Signature { const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); @@ -33895,6 +33895,9 @@ 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 (!headMessage && isCallExpression(node) && isSyntheticHasInstanceMethodCall(node)) { + 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]; @@ -33903,7 +33906,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { chain = chainDiagnosticMessages(chain, Diagnostics.The_last_overload_gave_the_following_error); chain = chainDiagnosticMessages(chain, Diagnostics.No_overload_matches_this_call); } - const headMessage = headMessageCallback?.(); if (headMessage) { chain = chainDiagnosticMessages(chain, headMessage); } @@ -33950,7 +33952,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { map(diags, createDiagnosticMessageChainFromDiagnostic), Diagnostics.No_overload_matches_this_call, ); - const headMessage = headMessageCallback?.(); if (headMessage) { chain = chainDiagnosticMessages(chain, headMessage); } @@ -33970,18 +33971,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else if (candidateForArgumentArityError) { - diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessageCallback?.())); + diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args, headMessage)); } else if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessageCallback?.()); + checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression | JsxOpeningLikeElement).typeArguments!, /*reportErrors*/ true, headMessage); } else { const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); if (signaturesWithCorrectTypeArgumentArity.length === 0) { - diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!, headMessageCallback?.())); + diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!, headMessage)); } else { - diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args, headMessageCallback?.())); + diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args, headMessage)); } } } @@ -34334,10 +34335,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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. - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags, () => - isSyntheticHasInstanceMethodCall(node) ? - 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 : - undefined); + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } function isGenericFunctionReturningFunction(signature: Signature) { @@ -34718,7 +34716,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveErrorCall(node); } - return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None, () => headMessage); + return resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None, headMessage); } function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature { @@ -37224,7 +37222,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const message = hasGlobalSymbolHasInstanceProperty ? - Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_an_object_type_with_a_Symbol_hasInstance_method_or_a_type_assignable_to_the_Function_interface_type : + 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 : Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type; error(right, message); } @@ -46800,14 +46798,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isBinaryExpression(node.parent)) { const type = getTypeOfExpression(node.parent.right); const hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(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 hasInstanceProperty; - // } - // } return hasInstanceMethodType?.symbol ?? type.symbol; } return undefined; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 99f8e2f1501f4..fb89c13e9ea83 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3671,7 +3671,7 @@ "category": "Error", "code": 2856 }, - "The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or 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": 2857 }, diff --git a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt index 620dcbfc0e512..c1d376418f321 100644 --- a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt @@ -7,18 +7,18 @@ instanceofOperatorWithInvalidOperands.es2015.ts(19,11): error TS2358: The left-h 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(35,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(36,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(37,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(38,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(39,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(40,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(41,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(42,24): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -instanceofOperatorWithInvalidOperands.es2015.ts(43,25): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(34,24): error TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +instanceofOperatorWithInvalidOperands.es2015.ts(46,25): error TS2857: 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 TS2855: 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; }'. @@ -79,41 +79,41 @@ instanceofOperatorWithInvalidOperands.es2015.ts(55,25): error TS2856: An object' var rb1 = x instanceof b1; ~~ -!!! error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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;}; diff --git a/tests/baselines/reference/symbolType1.errors.txt b/tests/baselines/reference/symbolType1.errors.txt index ab65833ad7375..912f1abd1db97 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. -symbolType1.ts(4,19): error TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +symbolType1.ts(2,19): error TS2857: 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 TS2857: 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 TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. +!!! error TS2857: 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 TS2857: The right-hand side of an 'instanceof' expression must be either of type 'any', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type. \ No newline at end of file +!!! error TS2857: 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 index 0b87da6891ad9..f4ec1af5217f5 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.errors.txt @@ -101,7 +101,7 @@ typeGuardsWithInstanceOfBySymbolHasInstance.ts(198,11): error TS2551: Property ' 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; @@ -164,7 +164,7 @@ typeGuardsWithInstanceOfBySymbolHasInstance.ts(198,11): error TS2551: Property ' 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/typeGuardsWithInstanceOfBySymbolHasInstance.js b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js index 7e3de3d6e7be5..07f4b5178a2e2 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.js @@ -65,7 +65,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; @@ -116,7 +116,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; @@ -238,7 +238,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; @@ -261,7 +261,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/typeGuardsWithInstanceOfBySymbolHasInstance.symbols b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols index 87fe09bfee5e3..6be6f0afde989 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.symbols @@ -187,7 +187,7 @@ var obj5: C1 | A; >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|C2. +if (obj5 instanceof C) { // narrowed to C1. >obj5 : Symbol(obj5, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 63, 3)) >C : Symbol(C, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 61, 11)) @@ -331,7 +331,7 @@ var obj9: E1 | A; >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 | E2 +if (obj9 instanceof E) { // narrowed to E1 >obj9 : Symbol(obj9, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 114, 3)) >E : Symbol(E, Decl(typeGuardsWithInstanceOfBySymbolHasInstance.ts, 112, 11)) diff --git a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types index 7c82a54446c2d..aefd4d384b694 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types +++ b/tests/baselines/reference/typeGuardsWithInstanceOfBySymbolHasInstance.types @@ -173,7 +173,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 @@ -309,7 +309,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/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 index 00f45c472422c..d47a87a483548 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfBySymbolHasInstance.ts @@ -64,7 +64,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; @@ -115,7 +115,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; From 559047e72ed967477aa762ddcf573d98607e95a3 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 22 Sep 2023 00:18:30 -0400 Subject: [PATCH 09/12] Comment cleanup --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fe43196e1d862..e456c474e8084 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28036,7 +28036,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getInstanceType(constructorType: Type, left: Expression, leftType: Type, right: Expression) { - // if rightType is an object type with a custom `[Symbol.hasInstance]` method, and that method has a type + // if constructorType is 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 hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(constructorType); @@ -33895,6 +33895,9 @@ 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 && isCallExpression(node) && isSyntheticHasInstanceMethodCall(node)) { 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; } @@ -34332,9 +34335,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolveErrorCall(node); } - // 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. return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags); } @@ -37201,7 +37201,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (!cache.hasSimpleUnrestrictedSingleCallSignature) { // 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)1. The call to + // 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 syntheticCall = createSyntheticHasInstanceMethodCall(left, leftType, right, rightType, hasInstanceMethodType); From 8af777e8270b79ad59f705ce670daa2f4fbed8cf Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 25 Sep 2023 20:47:24 -0400 Subject: [PATCH 10/12] Switch synthetic call to use use 'resolveSignature' flow --- src/compiler/checker.ts | 242 +++++++++--------- src/compiler/factory/nodeFactory.ts | 3 +- src/compiler/types.ts | 18 +- src/compiler/utilities.ts | 12 + src/compiler/utilitiesPublic.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 8 +- 6 files changed, 153 insertions(+), 131 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e456c474e8084..cbdd661e4feb9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -383,7 +383,6 @@ import { HasIllegalModifiers, HasInitializer, hasInitializer, - HasInstanceMethodType, hasJSDocNodes, hasJSDocParameterTags, hasJsonModuleEmitEnabled, @@ -428,6 +427,7 @@ import { InferenceInfo, InferencePriority, InferTypeNode, + InstanceofExpression, InstantiableType, InstantiationExpressionType, InterfaceDeclaration, @@ -563,6 +563,7 @@ import { isInJSDoc, isInJSFile, isInJsonFile, + isInstanceOfExpression, isInterfaceDeclaration, isInternalModuleImportEqualsDeclaration, isInTopLevelContext, @@ -688,6 +689,7 @@ import { isRestParameter, isRestTypeNode, isRightSideOfAccessExpression, + isRightSideOfInstanceofExpression, isRightSideOfQualifiedNameOrPropertyAccess, isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName, isSameEntityName, @@ -710,7 +712,6 @@ import { isStringOrNumericLiteralLike, isSuperCall, isSuperProperty, - isSyntheticExpression, isTaggedTemplateExpression, isTemplateSpan, isThisContainerOrFunctionBlock, @@ -810,7 +811,6 @@ import { LateBoundDeclaration, LateBoundName, LateVisibilityPaintedStatement, - LeftHandSideExpression, length, LiteralExpression, LiteralType, @@ -2212,7 +2212,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var potentialReflectCollisions: Node[] = []; var potentialUnusedRenamedBindingElementsInTypes: BindingElement[] = []; var awaitedTypeStack: number[] = []; - var hasGlobalSymbolHasInstanceProperty: boolean | undefined; + var hasGlobalSymbolHasInstancePropertyCache: boolean | undefined; var diagnostics = createDiagnosticCollection(); var suggestionDiagnostics = createDiagnosticCollection(); @@ -26850,7 +26850,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) { @@ -26859,7 +26859,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) { @@ -27714,7 +27718,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); @@ -28010,7 +28014,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)) { @@ -28023,7 +28027,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!isTypeDerivedFrom(rightType, globalObjectType)) { return type; } - const instanceType = mapType(rightType, t => getInstanceType(t, left, type, right)); + + // 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; + } + const instanceType = mapType(rightType, getInstanceType); // Don't narrow from `any` if the target type is exactly `Object` or `Function`, and narrow // in the false branch only if the target is a non-empty object type. if ( @@ -28035,22 +28051,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getNarrowedType(type, instanceType, assumeTrue, /*checkDerived*/ true); } - function getInstanceType(constructorType: Type, left: Expression, leftType: Type, right: Expression) { - // if constructorType is 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 hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(constructorType); - if (hasInstanceMethodType) { - const syntheticCall = createSyntheticHasInstanceMethodCall(left, leftType, right, constructorType, hasInstanceMethodType); - const signature = getEffectsSignature(syntheticCall); - const predicate = signature && getTypePredicateOfSignature(signature); - if (predicate && predicate.kind === TypePredicateKind.Identifier && predicate.parameterIndex === 0) { - return predicate.type; - } - if (!isTypeDerivedFrom(constructorType, globalFunctionType)) { - return leftType; - } - } + function getInstanceType(constructorType: Type) { const prototypePropertyType = getTypeOfPropertyOfType(constructorType, "prototype" as __String); if (prototypePropertyType && !isTypeAny(prototypePropertyType)) { return prototypePropertyType; @@ -32881,8 +32882,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); }); } @@ -32990,6 +32994,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) { @@ -33098,12 +33105,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; } @@ -33117,7 +33125,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) { @@ -33495,7 +33503,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 : @@ -33505,14 +33517,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isAccessExpression(callee)) { return callee.expression; } - if (isSyntheticExpression(callee)) { - return callee.thisArgument; - } } } - function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember, thisArgument?: LeftHandSideExpression) { - const result = parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource, thisArgument); + function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { + const result = parseNodeFactory.createSyntheticExpression(type, isSpread, tupleNameSource); setTextRange(result, parent); setParent(result, parent); return result; @@ -33535,6 +33544,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; } @@ -33791,15 +33803,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount); } - function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessage?: DiagnosticMessage | undefined): Signature { + function resolveCall(node: CallLikeExpression, signatures: readonly Signature[], candidatesOutArray: Signature[] | undefined, checkMode: CheckMode, callChainFlags: SignatureFlags, headMessage?: DiagnosticMessage): Signature { 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. @@ -33898,7 +33911,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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 && isCallExpression(node) && isSyntheticHasInstanceMethodCall(node)) { + 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) { @@ -34772,6 +34785,43 @@ 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))) { + // Do not indicate that `[Symbol.hasInstance]` is a valid option if it's not known to be present on `SymbolConstructor`. + const message = hasGlobalSymbolHasInstanceProperty() ? + 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 : + Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type; + error(node.right, message); + 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. @@ -34797,6 +34847,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."); } @@ -37135,42 +37187,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - /** - * Creates a synthetic `CallExpression` that reinterprets `left instanceof right` as `right[Symbol.hasInstance](left)` - * per the `InstanceofOperator` algorithm in the ECMAScript specification. - * @param left The left-hand expression of `instanceof` - * @param right The right-hand expression of `instanceof` - * @param leftType The type of the left-hand expression of `instanceof`. - * @param hasInstanceMethodType The type of the `[Symbol.hasInstance]` method of the right-hand expression of `instanceof`. - */ - function createSyntheticHasInstanceMethodCall(left: Expression, leftType: Type, right: Expression, rightType: Type, hasInstanceMethodType: Type) { - const thisArgument = createSyntheticExpression(right, rightType); - const syntheticExpression = createSyntheticExpression(right, hasInstanceMethodType, /*isSpread*/ false, /*tupleNameSource*/ undefined, thisArgument); - const syntheticArgument = createSyntheticExpression(left, leftType); - const syntheticCall = parseNodeFactory.createCallExpression(syntheticExpression, /*typeArguments*/ undefined, [syntheticArgument]); - setParent(syntheticCall, left.parent); - setTextRange(syntheticCall, left.parent); - return syntheticCall; - } - - /** - * Tests whether a `CallExpression` is a synthetic call to a `[Symbol.hasInstance]` method as would be produced by - * {@link createSyntheticHasInstanceMethodCall}. - */ - function isSyntheticHasInstanceMethodCall(node: CallExpression) { - return isSyntheticExpression(node.expression) && - node.arguments.length === 1 && - isSyntheticExpression(node.arguments[0]) && - isBinaryExpression(node.parent) && - node.parent.operatorToken.kind === SyntaxKind.InstanceOfKeyword && - node.parent.right === node.expression.parent && - node.parent.left === node.arguments[0].parent; - } - - function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type { + 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. @@ -37182,54 +37203,37 @@ 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); } - if (!isTypeAny(rightType)) { - // 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 hasInstanceMethodType = getSymbolHasInstanceMethodOfObjectType(rightType); - if (hasInstanceMethodType) { - // avoid a complex check for every `instanceof` when the `[Symbol.hasInstance]` method has a single - // call signature that neither restricts nor narrows (via type predicate) the LHS value, e.g. - // `(value: unknown) => boolean`. - const cache = hasInstanceMethodType as HasInstanceMethodType; - if (cache.hasSimpleUnrestrictedSingleCallSignature === undefined) { - const signature = getSingleCallSignature(hasInstanceMethodType); - cache.hasSimpleUnrestrictedSingleCallSignature = !!signature && signature.parameters.length === 1 && - !!(getTypeOfSymbol(signature.parameters[0]).flags & TypeFlags.AnyOrUnknown) && - !!signature.resolvedReturnType && - !!(signature.resolvedReturnType.flags & TypeFlags.Boolean); - } - if (!cache.hasSimpleUnrestrictedSingleCallSignature) { - // 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 syntheticCall = createSyntheticHasInstanceMethodCall(left, leftType, right, rightType, hasInstanceMethodType); - const returnType = getReturnTypeOfSignature(getResolvedSignature(syntheticCall)); - - // 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); - } - } - // NOTE: do not raise error if right is unknown as related error was already reported - if (!(hasInstanceMethodType || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { - // Do not indicate that `[Symbol.hasInstance]` is a valid option if it's not known to be present on `SymbolConstructor`. - if (hasGlobalSymbolHasInstanceProperty === undefined) { - const globalESSymbolConstructorSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); - hasGlobalSymbolHasInstanceProperty = !!globalESSymbolConstructorSymbol && getMembersOfSymbol(globalESSymbolConstructorSymbol).has("hasInstance" as __String); - } - const message = hasGlobalSymbolHasInstanceProperty ? - 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 : - Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type; - error(right, message); - } + 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; } + function hasGlobalSymbolHasInstanceProperty() { + if (hasGlobalSymbolHasInstancePropertyCache === undefined) { + const globalESSymbolConstructorSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); + hasGlobalSymbolHasInstancePropertyCache = !!globalESSymbolConstructorSymbol && getMembersOfSymbol(globalESSymbolConstructorSymbol).has("hasInstance" as __String); + } + return hasGlobalSymbolHasInstancePropertyCache; + } + function hasEmptyObjectIntersection(type: Type): boolean { return someType(type, t => t === unknownEmptyObjectType || !!(t.flags & TypeFlags.Intersection) && isEmptyAnonymousObjectType(getBaseConstraintOrType(t))); } @@ -37860,7 +37864,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: @@ -46056,6 +46060,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(); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index ec254ecbdb705..ededdbd057ab9 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -6212,12 +6212,11 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode // // @api - function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember, thisArgument?: LeftHandSideExpression) { + function createSyntheticExpression(type: Type, isSpread = false, tupleNameSource?: ParameterDeclaration | NamedTupleMember) { const node = createBaseNode(SyntaxKind.SyntheticExpression); node.type = type; node.isSpread = isSpread; node.tupleNameSource = tupleNameSource; - node.thisArgument = thisArgument; return node; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2b856c91694e7..162a3183b1eee 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2453,12 +2453,11 @@ export interface YieldExpression extends Expression { readonly expression?: Expression; } -export interface SyntheticExpression extends LeftHandSideExpression { +export interface SyntheticExpression extends Expression { readonly kind: SyntaxKind.SyntheticExpression; readonly isSpread: boolean; readonly type: Type; readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; - readonly thisArgument?: LeftHandSideExpression; } // see: https://tc39.github.io/ecma262/#prod-ExponentiationExpression @@ -3048,12 +3047,18 @@ 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; @@ -6500,11 +6505,6 @@ export interface PromiseOrAwaitableType extends ObjectType, UnionType { awaitedTypeOfType?: Type; } -/** @internal */ -export interface HasInstanceMethodType extends Type { - hasSimpleUnrestrictedSingleCallSignature?: boolean; -} - /** @internal */ export interface SyntheticDefaultModuleType extends Type { syntheticType?: Type; @@ -8789,7 +8789,7 @@ export interface NodeFactory { // // Synthetic Nodes // - /** @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember, thisArgument?: LeftHandSideExpression): SyntheticExpression; + /** @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember): SyntheticExpression; /** @internal */ createSyntaxList(children: Node[]): SyntaxList; // diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 4d63c9124a7ac..33306c97b82ef 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -231,6 +231,7 @@ import { IndexSignatureDeclaration, InitializedVariableDeclaration, insertSorted, + InstanceofExpression, InterfaceDeclaration, InternalEmitFlags, isAccessor, @@ -3149,6 +3150,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; } @@ -7269,6 +7272,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/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 0bf750f688dec..56ee00f89a04c 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1976,7 +1976,6 @@ function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean { case SyntaxKind.MetaProperty: case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression case SyntaxKind.MissingDeclaration: - case SyntaxKind.SyntheticExpression: // synthetic expressions are only used by the checker to substitute specific types for expression positions, so their precedence does not matter. return true; default: return false; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4247cd4a0f9fd..3397ace07ae9c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5358,12 +5358,11 @@ declare namespace ts { readonly asteriskToken?: AsteriskToken; readonly expression?: Expression; } - interface SyntheticExpression extends LeftHandSideExpression { + interface SyntheticExpression extends Expression { readonly kind: SyntaxKind.SyntheticExpression; readonly isSpread: boolean; readonly type: Type; readonly tupleNameSource?: ParameterDeclaration | NamedTupleMember; - readonly thisArgument?: LeftHandSideExpression; } type ExponentiationOperator = SyntaxKind.AsteriskAsteriskToken; type MultiplicativeOperator = SyntaxKind.AsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken; @@ -5587,7 +5586,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; From 1d90af1a214ca7d85526238c31ceacf82e418dbc Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 25 Sep 2023 20:59:52 -0400 Subject: [PATCH 11/12] Run formatting --- src/compiler/types.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 62169be2bc312..1531292cf33e1 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3057,8 +3057,7 @@ export type CallLikeExpression = | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement - | InstanceofExpression - ; + | InstanceofExpression; export interface AsExpression extends Expression { readonly kind: SyntaxKind.AsExpression; From 0554f56101c81f5dee49c8ea668fa3ff828ba4d1 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 29 Sep 2023 11:56:24 -0400 Subject: [PATCH 12/12] Remove branch for 'instanceof' error message reporting --- src/compiler/checker.ts | 15 +------ src/compiler/diagnosticMessages.json | 6 +-- .../reference/instanceofOperator.errors.txt | 8 ++-- ...ceofOperatorWithInvalidOperands.errors.txt | 44 +++++++++---------- ...ratorWithInvalidOperands.es2015.errors.txt | 44 +++++++++---------- .../reference/symbolType1.errors.txt | 8 ++-- 6 files changed, 54 insertions(+), 71 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cd3d9ef08fbfd..d63d9760172a0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2233,7 +2233,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var potentialReflectCollisions: Node[] = []; var potentialUnusedRenamedBindingElementsInTypes: BindingElement[] = []; var awaitedTypeStack: number[] = []; - var hasGlobalSymbolHasInstancePropertyCache: boolean | undefined; var diagnostics = createDiagnosticCollection(); var suggestionDiagnostics = createDiagnosticCollection(); @@ -34904,11 +34903,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // NOTE: do not raise error if right is unknown as related error was already reported else if (!(typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) { - // Do not indicate that `[Symbol.hasInstance]` is a valid option if it's not known to be present on `SymbolConstructor`. - const message = hasGlobalSymbolHasInstanceProperty() ? - 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 : - Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type; - error(node.right, message); + 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); } } @@ -37320,14 +37315,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return booleanType; } - function hasGlobalSymbolHasInstanceProperty() { - if (hasGlobalSymbolHasInstancePropertyCache === undefined) { - const globalESSymbolConstructorSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false); - hasGlobalSymbolHasInstancePropertyCache = !!globalESSymbolConstructorSymbol && getMembersOfSymbol(globalESSymbolConstructorSymbol).has("hasInstance" as __String); - } - return hasGlobalSymbolHasInstancePropertyCache; - } - function hasEmptyObjectIntersection(type: Type): boolean { return someType(type, t => t === unknownEmptyObjectType || !!(t.flags & TypeFlags.Intersection) && isEmptyAnonymousObjectType(getBaseConstraintOrType(t))); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5e521d6bf1982..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 }, @@ -3699,10 +3699,6 @@ "category": "Error", "code": 2861 }, - "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": 2862 - }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", 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 index d6d21ba31af39..f65722f6e3ef3 100644 --- a/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt +++ b/tests/baselines/reference/instanceofOperatorWithInvalidOperands.es2015.errors.txt @@ -7,18 +7,18 @@ instanceofOperatorWithInvalidOperands.es2015.ts(19,11): error TS2358: The left-h 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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 TS2862: 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(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 TS2862: 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,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; }'. @@ -79,41 +79,41 @@ instanceofOperatorWithInvalidOperands.es2015.ts(55,25): error TS2861: An object' var rb1 = x instanceof b1; ~~ -!!! error TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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 TS2862: 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 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;}; diff --git a/tests/baselines/reference/symbolType1.errors.txt b/tests/baselines/reference/symbolType1.errors.txt index cd92a0acb4078..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 TS2862: 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 TS2862: 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(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 TS2862: 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 TS2862: 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 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 TS2862: 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 +!!! 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