Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 128 additions & 11 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -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', an object type with a '[Symbol.hasInstance]()' method, or a type assignable to the 'Function' interface type.": {
"category": "Error",
"code": 2857
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
7 changes: 6 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/compiler/utilitiesPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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;
Loading