diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 81dc893976cd3..a3dfbe44a6b54 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37974,11 +37974,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { */ function getSymbolHasInstanceMethodOfObjectType(type: Type) { const hasInstancePropertyName = getPropertyNameForKnownSymbolName("hasInstance"); - const hasInstanceProperty = getPropertyOfObjectType(type, hasInstancePropertyName); - if (hasInstanceProperty) { - const hasInstancePropertyType = getTypeOfSymbol(hasInstanceProperty); - if (hasInstancePropertyType && getSignaturesOfType(hasInstancePropertyType, SignatureKind.Call).length !== 0) { - return hasInstancePropertyType; + if (allTypesAssignableToKind(type, TypeFlags.NonPrimitive)) { + const hasInstanceProperty = getPropertyOfType(type, hasInstancePropertyName); + if (hasInstanceProperty) { + const hasInstancePropertyType = getTypeOfSymbol(hasInstanceProperty); + if (hasInstancePropertyType && getSignaturesOfType(hasInstancePropertyType, SignatureKind.Call).length !== 0) { + return hasInstancePropertyType; + } } } } diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js index 0d4984e43e0a0..6d6f36a084f10 100644 --- a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.js @@ -115,7 +115,24 @@ if (obj instanceof A) { } if (obj instanceof B) { obj; // B -} +} + +// intersections +// https://github.com/microsoft/TypeScript/issues/56536 + +interface HasInstanceOf { [Symbol.hasInstance](x: unknown): boolean } +type Rhs14 = HasInstanceOf & object; +declare const rhs14: Rhs14; +lhs0 instanceof rhs14 && lhs0; + +// unions + +interface HasInstanceOf1 { [Symbol.hasInstance](x: unknown): x is Point } +interface HasInstanceOf2 { [Symbol.hasInstance](x: unknown): x is Line } +type Rhs15 = HasInstanceOf1 | HasInstanceOf2; +declare const rhs15: Rhs15; +lhs0 instanceof rhs15 && lhs0; + //// [instanceofOperatorWithRHSHasSymbolHasInstance.js] lhs0 instanceof rhs0 && lhs0; @@ -182,3 +199,5 @@ if (obj instanceof A) { if (obj instanceof B) { obj; // B } +lhs0 instanceof rhs14 && lhs0; +lhs0 instanceof rhs15 && lhs0; diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols index e2d111f8772be..d7243b4958aef 100644 --- a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.symbols @@ -555,3 +555,64 @@ if (obj instanceof B) { obj; // B >obj : Symbol(obj, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 108, 13)) } + +// intersections +// https://github.com/microsoft/TypeScript/issues/56536 + +interface HasInstanceOf { [Symbol.hasInstance](x: unknown): boolean } +>HasInstanceOf : Symbol(HasInstanceOf, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 114, 1)) +>[Symbol.hasInstance] : Symbol(HasInstanceOf[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 119, 25)) +>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, --, --)) +>x : Symbol(x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 119, 47)) + +type Rhs14 = HasInstanceOf & object; +>Rhs14 : Symbol(Rhs14, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 119, 69)) +>HasInstanceOf : Symbol(HasInstanceOf, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 114, 1)) + +declare const rhs14: Rhs14; +>rhs14 : Symbol(rhs14, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 121, 13)) +>Rhs14 : Symbol(Rhs14, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 119, 69)) + +lhs0 instanceof rhs14 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs14 : Symbol(rhs14, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 121, 13)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + +// unions + +interface HasInstanceOf1 { [Symbol.hasInstance](x: unknown): x is Point } +>HasInstanceOf1 : Symbol(HasInstanceOf1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 122, 30)) +>[Symbol.hasInstance] : Symbol(HasInstanceOf1[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 126, 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, --, --)) +>x : Symbol(x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 126, 48)) +>x : Symbol(x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 126, 48)) +>Point : Symbol(Point, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 0, 0)) + +interface HasInstanceOf2 { [Symbol.hasInstance](x: unknown): x is Line } +>HasInstanceOf2 : Symbol(HasInstanceOf2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 126, 73)) +>[Symbol.hasInstance] : Symbol(HasInstanceOf2[Symbol.hasInstance], Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 127, 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, --, --)) +>x : Symbol(x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 127, 48)) +>x : Symbol(x, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 127, 48)) +>Line : Symbol(Line, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 2, 46)) + +type Rhs15 = HasInstanceOf1 | HasInstanceOf2; +>Rhs15 : Symbol(Rhs15, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 127, 72)) +>HasInstanceOf1 : Symbol(HasInstanceOf1, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 122, 30)) +>HasInstanceOf2 : Symbol(HasInstanceOf2, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 126, 73)) + +declare const rhs15: Rhs15; +>rhs15 : Symbol(rhs15, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 129, 13)) +>Rhs15 : Symbol(Rhs15, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 127, 72)) + +lhs0 instanceof rhs15 && lhs0; +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) +>rhs15 : Symbol(rhs15, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 129, 13)) +>lhs0 : Symbol(lhs0, Decl(instanceofOperatorWithRHSHasSymbolHasInstance.ts, 21, 11)) + diff --git a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types index fc8be58916595..6b645c08bc58a 100644 --- a/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types +++ b/tests/baselines/reference/instanceofOperatorWithRHSHasSymbolHasInstance.types @@ -609,3 +609,56 @@ if (obj instanceof B) { obj; // B >obj : B } + +// intersections +// https://github.com/microsoft/TypeScript/issues/56536 + +interface HasInstanceOf { [Symbol.hasInstance](x: unknown): boolean } +>[Symbol.hasInstance] : (x: unknown) => boolean +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>x : unknown + +type Rhs14 = HasInstanceOf & object; +>Rhs14 : HasInstanceOf & object + +declare const rhs14: Rhs14; +>rhs14 : Rhs14 + +lhs0 instanceof rhs14 && lhs0; +>lhs0 instanceof rhs14 && lhs0 : any +>lhs0 instanceof rhs14 : boolean +>lhs0 : any +>rhs14 : Rhs14 +>lhs0 : any + +// unions + +interface HasInstanceOf1 { [Symbol.hasInstance](x: unknown): x is Point } +>[Symbol.hasInstance] : (x: unknown) => x is Point +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>x : unknown + +interface HasInstanceOf2 { [Symbol.hasInstance](x: unknown): x is Line } +>[Symbol.hasInstance] : (x: unknown) => x is Line +>Symbol.hasInstance : unique symbol +>Symbol : SymbolConstructor +>hasInstance : unique symbol +>x : unknown + +type Rhs15 = HasInstanceOf1 | HasInstanceOf2; +>Rhs15 : HasInstanceOf1 | HasInstanceOf2 + +declare const rhs15: Rhs15; +>rhs15 : Rhs15 + +lhs0 instanceof rhs15 && lhs0; +>lhs0 instanceof rhs15 && lhs0 : Point | Line +>lhs0 instanceof rhs15 : boolean +>lhs0 : any +>rhs15 : Rhs15 +>lhs0 : Point | Line + diff --git a/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts index 2b33ccb330c52..2148cbda0f4da 100644 --- a/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts +++ b/tests/cases/conformance/expressions/binaryOperators/instanceofOperator/instanceofOperatorWithRHSHasSymbolHasInstance.ts @@ -115,4 +115,20 @@ if (obj instanceof A) { } if (obj instanceof B) { obj; // B -} \ No newline at end of file +} + +// intersections +// https://github.com/microsoft/TypeScript/issues/56536 + +interface HasInstanceOf { [Symbol.hasInstance](x: unknown): boolean } +type Rhs14 = HasInstanceOf & object; +declare const rhs14: Rhs14; +lhs0 instanceof rhs14 && lhs0; + +// unions + +interface HasInstanceOf1 { [Symbol.hasInstance](x: unknown): x is Point } +interface HasInstanceOf2 { [Symbol.hasInstance](x: unknown): x is Line } +type Rhs15 = HasInstanceOf1 | HasInstanceOf2; +declare const rhs15: Rhs15; +lhs0 instanceof rhs15 && lhs0;