diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d96b7e24eaa1a..b839af02643b0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20597,7 +20597,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return; } } - message = Diagnostics.Type_0_is_not_assignable_to_type_1; + if (compilerOptions.pretty && useMultilineReportingForTypes(sourceType, targetType)) { + message = Diagnostics.Type_Colon_n_0_n_nis_not_assignable_to_type_Colon_n_1; + } + else { + message = Diagnostics.Type_0_is_not_assignable_to_type_1; + } } } else if (message === Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 @@ -20609,6 +20614,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { reportError(message, generalizedSourceType, targetType); } + function useMultilineReportingForTypes(source: string, target: string) { + return source.length > 30 || target.length > 30; + } + function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) { const sourceType = symbolValueDeclarationIsContextSensitive(source.symbol) ? typeToString(source, source.symbol.valueDeclaration) : typeToString(source); const targetType = symbolValueDeclarationIsContextSensitive(target.symbol) ? typeToString(target, target.symbol.valueDeclaration) : typeToString(target); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0d01c46edd7b5..3e2ec68f3c55e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3659,6 +3659,11 @@ "category": "Error", "code": 2854 }, + "Type:\\n{0}\\n\\nis not assignable to type:\\n{1}": { + "category": "Error", + "code": 2855 + }, + "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/newlinesOnLongMessagesWithPretty.errors.txt b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.errors.txt new file mode 100644 index 0000000000000..0d735ad5d37dc --- /dev/null +++ b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.errors.txt @@ -0,0 +1,51 @@ +newlinesOnLongMessagesWithPretty.ts:6:1 - error TS2855: Type:\nstring\n\nis not assignable to type:\n{ b: { c: { e: { f: number; }; }; }; } + +6 a = b +  ~ +newlinesOnLongMessagesWithPretty.ts:8:1 - error TS2855: Type:\n{ b: { c: { e: { f: number; }; }; }; }\n\nis not assignable to type:\nstring + +8 b = a +  ~ +newlinesOnLongMessagesWithPretty.ts:11:22 - error TS2322: Type '{}' is not assignable to type 'number'. + +11 a = { b: { c: { e: { f: {} } } } } +   ~ + + newlinesOnLongMessagesWithPretty.ts:2:26 + 2 let a = { b: { c: { e: { f: 123 } } } }; +    ~~~~~~ + The expected type comes from property 'f' which is declared here on type '{ f: number; }' +newlinesOnLongMessagesWithPretty.ts:14:1 - error TS2322: Type 'number' is not assignable to type 'string'. + +14 b = 123123 +  ~ + + +==== newlinesOnLongMessagesWithPretty.ts (4 errors) ==== + // a is 31 chars long + let a = { b: { c: { e: { f: 123 } } } }; + let b = "hello" + + // 'a' here is long enough to count in the source as a newline + a = b + ~ +!!! error TS2855: Type:\nstring\n\nis not assignable to type:\n{ b: { c: { e: { f: number; }; }; }; } + // 'a' here is long enough to count in the target as a newline + b = a + ~ +!!! error TS2855: Type:\n{ b: { c: { e: { f: number; }; }; }; }\n\nis not assignable to type:\nstring + + // This won't trigger it because we only show the relation instead + a = { b: { c: { e: { f: {} } } } } + ~ +!!! error TS2322: Type '{}' is not assignable to type 'number'. +!!! related TS6500 newlinesOnLongMessagesWithPretty.ts:2:26: The expected type comes from property 'f' which is declared here on type '{ f: number; }' + + // No newlines here because they're both short + b = 123123 + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + +Found 4 errors in the same file, starting at: newlinesOnLongMessagesWithPretty.ts:6 + diff --git a/tests/baselines/reference/newlinesOnLongMessagesWithPretty.js b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.js new file mode 100644 index 0000000000000..e1d02717b0ded --- /dev/null +++ b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/newlinesOnLongMessagesWithPretty.ts] //// + +//// [newlinesOnLongMessagesWithPretty.ts] +// a is 31 chars long +let a = { b: { c: { e: { f: 123 } } } }; +let b = "hello" + +// 'a' here is long enough to count in the source as a newline +a = b +// 'a' here is long enough to count in the target as a newline +b = a + +// This won't trigger it because we only show the relation instead +a = { b: { c: { e: { f: {} } } } } + +// No newlines here because they're both short +b = 123123 + + + +//// [newlinesOnLongMessagesWithPretty.js] +// a is 31 chars long +var a = { b: { c: { e: { f: 123 } } } }; +var b = "hello"; +// 'a' here is long enough to count in the source as a newline +a = b; +// 'a' here is long enough to count in the target as a newline +b = a; +// This won't trigger it because we only show the relation instead +a = { b: { c: { e: { f: {} } } } }; +// No newlines here because they're both short +b = 123123; diff --git a/tests/baselines/reference/newlinesOnLongMessagesWithPretty.symbols b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.symbols new file mode 100644 index 0000000000000..981dd80115332 --- /dev/null +++ b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/newlinesOnLongMessagesWithPretty.ts] //// + +=== newlinesOnLongMessagesWithPretty.ts === +// a is 31 chars long +let a = { b: { c: { e: { f: 123 } } } }; +>a : Symbol(a, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 3)) +>b : Symbol(b, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 9)) +>c : Symbol(c, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 14)) +>e : Symbol(e, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 19)) +>f : Symbol(f, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 24)) + +let b = "hello" +>b : Symbol(b, Decl(newlinesOnLongMessagesWithPretty.ts, 2, 3)) + +// 'a' here is long enough to count in the source as a newline +a = b +>a : Symbol(a, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 3)) +>b : Symbol(b, Decl(newlinesOnLongMessagesWithPretty.ts, 2, 3)) + +// 'a' here is long enough to count in the target as a newline +b = a +>b : Symbol(b, Decl(newlinesOnLongMessagesWithPretty.ts, 2, 3)) +>a : Symbol(a, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 3)) + +// This won't trigger it because we only show the relation instead +a = { b: { c: { e: { f: {} } } } } +>a : Symbol(a, Decl(newlinesOnLongMessagesWithPretty.ts, 1, 3)) +>b : Symbol(b, Decl(newlinesOnLongMessagesWithPretty.ts, 10, 5)) +>c : Symbol(c, Decl(newlinesOnLongMessagesWithPretty.ts, 10, 10)) +>e : Symbol(e, Decl(newlinesOnLongMessagesWithPretty.ts, 10, 15)) +>f : Symbol(f, Decl(newlinesOnLongMessagesWithPretty.ts, 10, 20)) + +// No newlines here because they're both short +b = 123123 +>b : Symbol(b, Decl(newlinesOnLongMessagesWithPretty.ts, 2, 3)) + + diff --git a/tests/baselines/reference/newlinesOnLongMessagesWithPretty.types b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.types new file mode 100644 index 0000000000000..20f654c8a16d2 --- /dev/null +++ b/tests/baselines/reference/newlinesOnLongMessagesWithPretty.types @@ -0,0 +1,53 @@ +//// [tests/cases/compiler/newlinesOnLongMessagesWithPretty.ts] //// + +=== newlinesOnLongMessagesWithPretty.ts === +// a is 31 chars long +let a = { b: { c: { e: { f: 123 } } } }; +>a : { b: { c: { e: { f: number; }; }; }; } +>{ b: { c: { e: { f: 123 } } } } : { b: { c: { e: { f: number; }; }; }; } +>b : { c: { e: { f: number; }; }; } +>{ c: { e: { f: 123 } } } : { c: { e: { f: number; }; }; } +>c : { e: { f: number; }; } +>{ e: { f: 123 } } : { e: { f: number; }; } +>e : { f: number; } +>{ f: 123 } : { f: number; } +>f : number +>123 : 123 + +let b = "hello" +>b : string +>"hello" : "hello" + +// 'a' here is long enough to count in the source as a newline +a = b +>a = b : string +>a : { b: { c: { e: { f: number; }; }; }; } +>b : string + +// 'a' here is long enough to count in the target as a newline +b = a +>b = a : { b: { c: { e: { f: number; }; }; }; } +>b : string +>a : { b: { c: { e: { f: number; }; }; }; } + +// This won't trigger it because we only show the relation instead +a = { b: { c: { e: { f: {} } } } } +>a = { b: { c: { e: { f: {} } } } } : { b: { c: { e: { f: {}; }; }; }; } +>a : { b: { c: { e: { f: number; }; }; }; } +>{ b: { c: { e: { f: {} } } } } : { b: { c: { e: { f: {}; }; }; }; } +>b : { c: { e: { f: {}; }; }; } +>{ c: { e: { f: {} } } } : { c: { e: { f: {}; }; }; } +>c : { e: { f: {}; }; } +>{ e: { f: {} } } : { e: { f: {}; }; } +>e : { f: {}; } +>{ f: {} } : { f: {}; } +>f : {} +>{} : {} + +// No newlines here because they're both short +b = 123123 +>b = 123123 : 123123 +>b : string +>123123 : 123123 + + diff --git a/tests/cases/compiler/newlinesOnLongMessagesWithPretty.ts b/tests/cases/compiler/newlinesOnLongMessagesWithPretty.ts new file mode 100644 index 0000000000000..820eaf4616672 --- /dev/null +++ b/tests/cases/compiler/newlinesOnLongMessagesWithPretty.ts @@ -0,0 +1,17 @@ +// @pretty: true + +// a is 31 chars long +let a = { b: { c: { e: { f: 123 } } } }; +let b = "hello" + +// 'a' here is long enough to count in the source as a newline +a = b +// 'a' here is long enough to count in the target as a newline +b = a + +// This won't trigger it because we only show the relation instead +a = { b: { c: { e: { f: {} } } } } + +// No newlines here because they're both short +b = 123123 +