diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8568cd5feed..bc8af9e6322 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6258,13 +6258,20 @@ namespace ts { targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); } + // check if trying to relate primitives to the boxed/apparent backing types. + if ((sourceType === "Number" && targetType === "number") || + (sourceType === "String" && targetType === "string") || + (sourceType === "Boolean" && targetType === "boolean")) { + reportError(Diagnostics._0_is_a_primitive_type_while_1_is_a_boxed_object_Prefer_using_0_when_possible, targetType, sourceType); + } + if (!message) { message = relation === comparableRelation ? Diagnostics.Type_0_is_not_comparable_to_type_1 : Diagnostics.Type_0_is_not_assignable_to_type_1; } - reportError(message, sourceType, targetType); + reportError(message, sourceType, targetType); } // Compare two types and return diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6210a20afa6..fb8bc21ec95 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1955,6 +1955,10 @@ "category": "Error", "code": 2691 }, + "'{0}' is a primitive type while '{1}' is a boxed object. Prefer using '{0}' when possible.": { + "category": "Error", + "code": 2692 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/tests/baselines/reference/apparentTypeSubtyping.errors.txt b/tests/baselines/reference/apparentTypeSubtyping.errors.txt index e1a53ef6a73..c19cfa44360 100644 --- a/tests/baselines/reference/apparentTypeSubtyping.errors.txt +++ b/tests/baselines/reference/apparentTypeSubtyping.errors.txt @@ -1,6 +1,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts(9,7): error TS2415: Class 'Derived' incorrectly extends base class 'Base'. Types of property 'x' are incompatible. Type 'String' is not assignable to type 'string'. + 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtyping.ts (1 errors) ==== @@ -17,6 +18,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSubtypi !!! error TS2415: Class 'Derived' incorrectly extends base class 'Base'. !!! error TS2415: Types of property 'x' are incompatible. !!! error TS2415: Type 'String' is not assignable to type 'string'. +!!! error TS2415: 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. x: String; } diff --git a/tests/baselines/reference/apparentTypeSupertype.errors.txt b/tests/baselines/reference/apparentTypeSupertype.errors.txt index 5fe5c92a5b3..b7195557e8d 100644 --- a/tests/baselines/reference/apparentTypeSupertype.errors.txt +++ b/tests/baselines/reference/apparentTypeSupertype.errors.txt @@ -2,6 +2,7 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty Types of property 'x' are incompatible. Type 'U' is not assignable to type 'string'. Type 'String' is not assignable to type 'string'. + 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSupertype.ts (1 errors) ==== @@ -19,5 +20,6 @@ tests/cases/conformance/types/typeRelationships/apparentType/apparentTypeSuperty !!! error TS2415: Types of property 'x' are incompatible. !!! error TS2415: Type 'U' is not assignable to type 'string'. !!! error TS2415: Type 'String' is not assignable to type 'string'. +!!! error TS2415: 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. x: U; } \ No newline at end of file diff --git a/tests/baselines/reference/arrayLiterals3.errors.txt b/tests/baselines/reference/arrayLiterals3.errors.txt index 8e6c7eccf81..eb0c6dc51b7 100644 --- a/tests/baselines/reference/arrayLiterals3.errors.txt +++ b/tests/baselines/reference/arrayLiterals3.errors.txt @@ -18,6 +18,7 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error Types of parameters 'items' and 'items' are incompatible. Type 'Number' is not assignable to type 'string | number'. Type 'Number' is not assignable to type 'number'. + 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. ==== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts (6 errors) ==== @@ -81,4 +82,5 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error !!! error TS2322: Types of parameters 'items' and 'items' are incompatible. !!! error TS2322: Type 'Number' is not assignable to type 'string | number'. !!! error TS2322: Type 'Number' is not assignable to type 'number'. +!!! error TS2322: 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. \ No newline at end of file diff --git a/tests/baselines/reference/assignFromBooleanInterface.errors.txt b/tests/baselines/reference/assignFromBooleanInterface.errors.txt index 4b06603a9bf..f5c92a47569 100644 --- a/tests/baselines/reference/assignFromBooleanInterface.errors.txt +++ b/tests/baselines/reference/assignFromBooleanInterface.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface.ts(3,1): error TS2322: Type 'Boolean' is not assignable to type 'boolean'. + 'boolean' is a primitive type while 'Boolean' is a boxed object. Prefer using 'boolean' when possible. ==== tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface.ts (1 errors) ==== @@ -7,4 +8,5 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface.ts(3 x = a; ~ !!! error TS2322: Type 'Boolean' is not assignable to type 'boolean'. +!!! error TS2322: 'boolean' is a primitive type while 'Boolean' is a boxed object. Prefer using 'boolean' when possible. a = x; \ No newline at end of file diff --git a/tests/baselines/reference/assignFromBooleanInterface2.errors.txt b/tests/baselines/reference/assignFromBooleanInterface2.errors.txt index c03eab60c74..bfbf56eec5a 100644 --- a/tests/baselines/reference/assignFromBooleanInterface2.errors.txt +++ b/tests/baselines/reference/assignFromBooleanInterface2.errors.txt @@ -3,6 +3,7 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts( Type '() => Object' is not assignable to type '() => boolean'. Type 'Object' is not assignable to type 'boolean'. tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(19,1): error TS2322: Type 'Boolean' is not assignable to type 'boolean'. + 'boolean' is a primitive type while 'Boolean' is a boxed object. Prefer using 'boolean' when possible. tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(20,1): error TS2322: Type 'NotBoolean' is not assignable to type 'boolean'. @@ -33,6 +34,7 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts( x = a; // expected error ~ !!! error TS2322: Type 'Boolean' is not assignable to type 'boolean'. +!!! error TS2322: 'boolean' is a primitive type while 'Boolean' is a boxed object. Prefer using 'boolean' when possible. x = b; // expected error ~ !!! error TS2322: Type 'NotBoolean' is not assignable to type 'boolean'. diff --git a/tests/baselines/reference/assignFromNumberInterface.errors.txt b/tests/baselines/reference/assignFromNumberInterface.errors.txt index 0c8c4a5f5ac..e68ec76f68f 100644 --- a/tests/baselines/reference/assignFromNumberInterface.errors.txt +++ b/tests/baselines/reference/assignFromNumberInterface.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/types/primitives/number/assignFromNumberInterface.ts(3,1): error TS2322: Type 'Number' is not assignable to type 'number'. + 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. ==== tests/cases/conformance/types/primitives/number/assignFromNumberInterface.ts (1 errors) ==== @@ -7,4 +8,5 @@ tests/cases/conformance/types/primitives/number/assignFromNumberInterface.ts(3,1 x = a; ~ !!! error TS2322: Type 'Number' is not assignable to type 'number'. +!!! error TS2322: 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. a = x; \ No newline at end of file diff --git a/tests/baselines/reference/assignFromNumberInterface2.errors.txt b/tests/baselines/reference/assignFromNumberInterface2.errors.txt index 85639cdeeaf..5cae4654760 100644 --- a/tests/baselines/reference/assignFromNumberInterface2.errors.txt +++ b/tests/baselines/reference/assignFromNumberInterface2.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/types/primitives/number/assignFromNumberInterface2.ts(24,1): error TS2322: Type 'Number' is not assignable to type 'number'. + 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. tests/cases/conformance/types/primitives/number/assignFromNumberInterface2.ts(25,1): error TS2322: Type 'NotNumber' is not assignable to type 'number'. @@ -29,6 +30,7 @@ tests/cases/conformance/types/primitives/number/assignFromNumberInterface2.ts(25 x = a; // expected error ~ !!! error TS2322: Type 'Number' is not assignable to type 'number'. +!!! error TS2322: 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. x = b; // expected error ~ !!! error TS2322: Type 'NotNumber' is not assignable to type 'number'. diff --git a/tests/baselines/reference/assignFromStringInterface.errors.txt b/tests/baselines/reference/assignFromStringInterface.errors.txt index 6ec8afad120..80268f4b06a 100644 --- a/tests/baselines/reference/assignFromStringInterface.errors.txt +++ b/tests/baselines/reference/assignFromStringInterface.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/types/primitives/string/assignFromStringInterface.ts(3,1): error TS2322: Type 'String' is not assignable to type 'string'. + 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. ==== tests/cases/conformance/types/primitives/string/assignFromStringInterface.ts (1 errors) ==== @@ -7,4 +8,5 @@ tests/cases/conformance/types/primitives/string/assignFromStringInterface.ts(3,1 x = a; ~ !!! error TS2322: Type 'String' is not assignable to type 'string'. +!!! error TS2322: 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. a = x; \ No newline at end of file diff --git a/tests/baselines/reference/assignFromStringInterface2.errors.txt b/tests/baselines/reference/assignFromStringInterface2.errors.txt index 4e09eb6eacb..d20bdaaba32 100644 --- a/tests/baselines/reference/assignFromStringInterface2.errors.txt +++ b/tests/baselines/reference/assignFromStringInterface2.errors.txt @@ -1,4 +1,5 @@ tests/cases/conformance/types/primitives/string/assignFromStringInterface2.ts(47,1): error TS2322: Type 'String' is not assignable to type 'string'. + 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. tests/cases/conformance/types/primitives/string/assignFromStringInterface2.ts(48,1): error TS2322: Type 'NotString' is not assignable to type 'string'. @@ -52,6 +53,7 @@ tests/cases/conformance/types/primitives/string/assignFromStringInterface2.ts(48 x = a; // expected error ~ !!! error TS2322: Type 'String' is not assignable to type 'string'. +!!! error TS2322: 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. x = b; // expected error ~ !!! error TS2322: Type 'NotString' is not assignable to type 'string'. diff --git a/tests/baselines/reference/nativeToBoxedTypes.errors.txt b/tests/baselines/reference/nativeToBoxedTypes.errors.txt new file mode 100644 index 00000000000..c471e6b0e7b --- /dev/null +++ b/tests/baselines/reference/nativeToBoxedTypes.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/nativeToBoxedTypes.ts(3,1): error TS2322: Type 'Number' is not assignable to type 'number'. + 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. +tests/cases/compiler/nativeToBoxedTypes.ts(7,1): error TS2322: Type 'String' is not assignable to type 'string'. + 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. +tests/cases/compiler/nativeToBoxedTypes.ts(11,1): error TS2322: Type 'Boolean' is not assignable to type 'boolean'. + 'boolean' is a primitive type while 'Boolean' is a boxed object. Prefer using 'boolean' when possible. + + +==== tests/cases/compiler/nativeToBoxedTypes.ts (3 errors) ==== + var N = new Number(); + var n = 100; + n = N; + ~ +!!! error TS2322: Type 'Number' is not assignable to type 'number'. +!!! error TS2322: 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. + + var S = new String(); + var s = "foge"; + s = S; + ~ +!!! error TS2322: Type 'String' is not assignable to type 'string'. +!!! error TS2322: 'string' is a primitive type while 'String' is a boxed object. Prefer using 'string' when possible. + + var B = new Boolean(); + var b = true; + b = B; + ~ +!!! error TS2322: Type 'Boolean' is not assignable to type 'boolean'. +!!! error TS2322: 'boolean' is a primitive type while 'Boolean' is a boxed object. Prefer using 'boolean' when possible. \ No newline at end of file diff --git a/tests/baselines/reference/nativeToBoxedTypes.js b/tests/baselines/reference/nativeToBoxedTypes.js new file mode 100644 index 00000000000..074b39fa08d --- /dev/null +++ b/tests/baselines/reference/nativeToBoxedTypes.js @@ -0,0 +1,23 @@ +//// [nativeToBoxedTypes.ts] +var N = new Number(); +var n = 100; +n = N; + +var S = new String(); +var s = "foge"; +s = S; + +var B = new Boolean(); +var b = true; +b = B; + +//// [nativeToBoxedTypes.js] +var N = new Number(); +var n = 100; +n = N; +var S = new String(); +var s = "foge"; +s = S; +var B = new Boolean(); +var b = true; +b = B; diff --git a/tests/baselines/reference/primitiveMembers.errors.txt b/tests/baselines/reference/primitiveMembers.errors.txt index da8b75f9bc5..24f02486d00 100644 --- a/tests/baselines/reference/primitiveMembers.errors.txt +++ b/tests/baselines/reference/primitiveMembers.errors.txt @@ -1,5 +1,6 @@ tests/cases/compiler/primitiveMembers.ts(5,3): error TS2339: Property 'toBAZ' does not exist on type 'number'. tests/cases/compiler/primitiveMembers.ts(11,1): error TS2322: Type 'Number' is not assignable to type 'number'. + 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. ==== tests/cases/compiler/primitiveMembers.ts (2 errors) ==== @@ -18,6 +19,7 @@ tests/cases/compiler/primitiveMembers.ts(11,1): error TS2322: Type 'Number' is n n = N; // should not work, as 'number' has a different brand ~ !!! error TS2322: Type 'Number' is not assignable to type 'number'. +!!! error TS2322: 'number' is a primitive type while 'Number' is a boxed object. Prefer using 'number' when possible. N = n; // should work var o: Object = {} diff --git a/tests/cases/compiler/nativeToBoxedTypes.ts b/tests/cases/compiler/nativeToBoxedTypes.ts new file mode 100644 index 00000000000..6cd51251b06 --- /dev/null +++ b/tests/cases/compiler/nativeToBoxedTypes.ts @@ -0,0 +1,11 @@ +var N = new Number(); +var n = 100; +n = N; + +var S = new String(); +var s = "foge"; +s = S; + +var B = new Boolean(); +var b = true; +b = B; \ No newline at end of file