diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 78ff1efc86..d1f8d0790e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3322,6 +3322,16 @@ namespace ts { return result; } + function getTypeNamesForErrorDisplay(left: Type, right: Type): [string, string] { + let leftStr = typeToString(left); + let rightStr = typeToString(right); + if (leftStr === rightStr) { + leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); + rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); + } + return [leftStr, rightStr]; + } + function toNodeBuilderFlags(flags = TypeFormatFlags.None): NodeBuilderFlags { return flags & TypeFormatFlags.NodeBuilderFlagsMask; } @@ -12253,12 +12263,7 @@ namespace ts { } function reportRelationError(message: DiagnosticMessage | undefined, source: Type, target: Type) { - let sourceType = typeToString(source); - let targetType = typeToString(target); - if (sourceType === targetType) { - sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); - targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); - } + const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target); if (!message) { if (relation === comparableRelation) { @@ -13209,7 +13214,7 @@ namespace ts { } if (props.length === 1) { const propName = symbolToString(unmatchedProperty); - reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, typeToString(source), typeToString(target)); + reportError(Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName, ...getTypeNamesForErrorDisplay(source, target)); if (length(unmatchedProperty.declarations)) { associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); } @@ -23452,8 +23457,7 @@ namespace ts { } function reportOperatorError() { - const leftStr = typeToString(leftType); - const rightStr = typeToString(rightType); + const [leftStr, rightStr] = getTypeNamesForErrorDisplay(leftType, rightType); const errNode = errorNode || operatorToken; if (!tryGiveBetterPrimaryError(errNode, leftStr, rightStr)) { error( diff --git a/tests/baselines/reference/clodulesDerivedClasses.errors.txt b/tests/baselines/reference/clodulesDerivedClasses.errors.txt index 958812b9b8..5bb3ff2983 100644 --- a/tests/baselines/reference/clodulesDerivedClasses.errors.txt +++ b/tests/baselines/reference/clodulesDerivedClasses.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/clodulesDerivedClasses.ts(9,7): error TS2417: Class static side 'typeof Path' incorrectly extends base class static side 'typeof Shape'. Types of property 'Utils' are incompatible. - Property 'convert' is missing in type 'typeof Utils' but required in type 'typeof Utils'. + Property 'convert' is missing in type 'typeof Path.Utils' but required in type 'typeof Shape.Utils'. ==== tests/cases/compiler/clodulesDerivedClasses.ts (1 errors) ==== @@ -16,7 +16,7 @@ tests/cases/compiler/clodulesDerivedClasses.ts(9,7): error TS2417: Class static ~~~~ !!! error TS2417: Class static side 'typeof Path' incorrectly extends base class static side 'typeof Shape'. !!! error TS2417: Types of property 'Utils' are incompatible. -!!! error TS2417: Property 'convert' is missing in type 'typeof Utils' but required in type 'typeof Utils'. +!!! error TS2417: Property 'convert' is missing in type 'typeof Path.Utils' but required in type 'typeof Shape.Utils'. !!! related TS2728 tests/cases/compiler/clodulesDerivedClasses.ts:6:21: 'convert' is declared here. name: string; diff --git a/tests/baselines/reference/differentTypesWithSameName.errors.txt b/tests/baselines/reference/differentTypesWithSameName.errors.txt index b027d5be93..b8b4b6e859 100644 --- a/tests/baselines/reference/differentTypesWithSameName.errors.txt +++ b/tests/baselines/reference/differentTypesWithSameName.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/differentTypesWithSameName.ts(16,15): error TS2345: Argument of type 'variable' is not assignable to parameter of type 'm.variable'. - Property 's' is missing in type 'variable' but required in type 'variable'. + Property 's' is missing in type 'variable' but required in type 'm.variable'. ==== tests/cases/compiler/differentTypesWithSameName.ts (1 errors) ==== @@ -21,5 +21,5 @@ tests/cases/compiler/differentTypesWithSameName.ts(16,15): error TS2345: Argumen m.doSomething(v); ~ !!! error TS2345: Argument of type 'variable' is not assignable to parameter of type 'm.variable'. -!!! error TS2345: Property 's' is missing in type 'variable' but required in type 'variable'. +!!! error TS2345: Property 's' is missing in type 'variable' but required in type 'm.variable'. !!! related TS2728 tests/cases/compiler/differentTypesWithSameName.ts:3:5: 's' is declared here. \ No newline at end of file diff --git a/tests/baselines/reference/errorWithSameNameType.errors.txt b/tests/baselines/reference/errorWithSameNameType.errors.txt new file mode 100644 index 0000000000..2c5eeed900 --- /dev/null +++ b/tests/baselines/reference/errorWithSameNameType.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/c.ts(7,5): error TS2367: This condition will always return 'false' since the types 'import("tests/cases/compiler/a").F' and 'import("tests/cases/compiler/b").F' have no overlap. +tests/cases/compiler/c.ts(11,1): error TS2741: Property 'foo1' is missing in type 'import("tests/cases/compiler/b").F' but required in type 'import("tests/cases/compiler/a").F'. + + +==== tests/cases/compiler/a.ts (0 errors) ==== + export interface F { + foo1: number + } + +==== tests/cases/compiler/b.ts (0 errors) ==== + export interface F { + foo2: number + } + +==== tests/cases/compiler/c.ts (2 errors) ==== + import * as A from './a' + import * as B from './b' + + let a: A.F + let b: B.F + + if (a === b) { + ~~~~~~~ +!!! error TS2367: This condition will always return 'false' since the types 'import("tests/cases/compiler/a").F' and 'import("tests/cases/compiler/b").F' have no overlap. + + } + + a = b + ~ +!!! error TS2741: Property 'foo1' is missing in type 'import("tests/cases/compiler/b").F' but required in type 'import("tests/cases/compiler/a").F'. +!!! related TS2728 tests/cases/compiler/a.ts:2:5: 'foo1' is declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/errorWithSameNameType.js b/tests/baselines/reference/errorWithSameNameType.js new file mode 100644 index 0000000000..85dba75385 --- /dev/null +++ b/tests/baselines/reference/errorWithSameNameType.js @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/errorWithSameNameType.ts] //// + +//// [a.ts] +export interface F { + foo1: number +} + +//// [b.ts] +export interface F { + foo2: number +} + +//// [c.ts] +import * as A from './a' +import * as B from './b' + +let a: A.F +let b: B.F + +if (a === b) { + +} + +a = b + + +//// [a.js] +"use strict"; +exports.__esModule = true; +//// [b.js] +"use strict"; +exports.__esModule = true; +//// [c.js] +"use strict"; +exports.__esModule = true; +var a; +var b; +if (a === b) { +} +a = b; diff --git a/tests/baselines/reference/errorWithSameNameType.symbols b/tests/baselines/reference/errorWithSameNameType.symbols new file mode 100644 index 0000000000..a197e578d6 --- /dev/null +++ b/tests/baselines/reference/errorWithSameNameType.symbols @@ -0,0 +1,43 @@ +=== tests/cases/compiler/a.ts === +export interface F { +>F : Symbol(F, Decl(a.ts, 0, 0)) + + foo1: number +>foo1 : Symbol(F.foo1, Decl(a.ts, 0, 20)) +} + +=== tests/cases/compiler/b.ts === +export interface F { +>F : Symbol(F, Decl(b.ts, 0, 0)) + + foo2: number +>foo2 : Symbol(F.foo2, Decl(b.ts, 0, 20)) +} + +=== tests/cases/compiler/c.ts === +import * as A from './a' +>A : Symbol(A, Decl(c.ts, 0, 6)) + +import * as B from './b' +>B : Symbol(B, Decl(c.ts, 1, 6)) + +let a: A.F +>a : Symbol(a, Decl(c.ts, 3, 3)) +>A : Symbol(A, Decl(c.ts, 0, 6)) +>F : Symbol(A.F, Decl(a.ts, 0, 0)) + +let b: B.F +>b : Symbol(b, Decl(c.ts, 4, 3)) +>B : Symbol(B, Decl(c.ts, 1, 6)) +>F : Symbol(B.F, Decl(b.ts, 0, 0)) + +if (a === b) { +>a : Symbol(a, Decl(c.ts, 3, 3)) +>b : Symbol(b, Decl(c.ts, 4, 3)) + +} + +a = b +>a : Symbol(a, Decl(c.ts, 3, 3)) +>b : Symbol(b, Decl(c.ts, 4, 3)) + diff --git a/tests/baselines/reference/errorWithSameNameType.types b/tests/baselines/reference/errorWithSameNameType.types new file mode 100644 index 0000000000..472f9d1e81 --- /dev/null +++ b/tests/baselines/reference/errorWithSameNameType.types @@ -0,0 +1,39 @@ +=== tests/cases/compiler/a.ts === +export interface F { + foo1: number +>foo1 : number +} + +=== tests/cases/compiler/b.ts === +export interface F { + foo2: number +>foo2 : number +} + +=== tests/cases/compiler/c.ts === +import * as A from './a' +>A : typeof A + +import * as B from './b' +>B : typeof B + +let a: A.F +>a : A.F +>A : any + +let b: B.F +>b : B.F +>B : any + +if (a === b) { +>a === b : boolean +>a : A.F +>b : B.F + +} + +a = b +>a = b : B.F +>a : A.F +>b : B.F + diff --git a/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt b/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt index d052166905..31848458a8 100644 --- a/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt +++ b/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt @@ -19,7 +19,7 @@ tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAnd tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(50,5): error TS2322: Type 'typeof N' is not assignable to type 'typeof M'. Types of property 'A' are incompatible. Type 'typeof N.A' is not assignable to type 'typeof M.A'. - Property 'name' is missing in type 'A' but required in type 'A'. + Property 'name' is missing in type 'N.A' but required in type 'M.A'. tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(51,5): error TS2322: Type 'N.A' is not assignable to type 'M.A'. tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(52,5): error TS2322: Type '(x: number) => boolean' is not assignable to type '(x: number) => string'. Type 'boolean' is not assignable to type 'string'. @@ -114,7 +114,7 @@ tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAnd !!! error TS2322: Type 'typeof N' is not assignable to type 'typeof M'. !!! error TS2322: Types of property 'A' are incompatible. !!! error TS2322: Type 'typeof N.A' is not assignable to type 'typeof M.A'. -!!! error TS2322: Property 'name' is missing in type 'A' but required in type 'A'. +!!! error TS2322: Property 'name' is missing in type 'N.A' but required in type 'M.A'. !!! related TS2728 tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts:20:9: 'name' is declared here. var aClassInModule: M.A = new N.A(); ~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt index 09653e2d35..c4a7c6809b 100644 --- a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__predomBrand' is missing in type 'Element' but required in type 'Element'. +tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__predomBrand' is missing in type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' but required in type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'. tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'. tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. Property '__domBrand' is missing in type 'MyClass' but required in type 'ElementClass'. tests/cases/conformance/jsx/inline/index.tsx(21,63): error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'. tests/cases/conformance/jsx/inline/index.tsx(21,63): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements. -tests/cases/conformance/jsx/inline/index.tsx(24,42): error TS2741: Property '__domBrand' is missing in type 'Element' but required in type 'Element'. +tests/cases/conformance/jsx/inline/index.tsx(24,42): error TS2741: Property '__domBrand' is missing in type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element' but required in type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element'. tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element'. @@ -75,7 +75,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import( let elem = prerendered; elem = ; // Expect assignability error here ~~~~ -!!! error TS2741: Property '__predomBrand' is missing in type 'Element' but required in type 'Element'. +!!! error TS2741: Property '__predomBrand' is missing in type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element' but required in type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'. !!! related TS2728 tests/cases/conformance/jsx/inline/renderer2.d.ts:7:13: '__predomBrand' is declared here. const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) =>

{props.x} + {props.y} = {props.x + props.y}{props.children}

; @@ -107,7 +107,7 @@ tests/cases/conformance/jsx/inline/index.tsx(24,48): error TS2322: Type 'import( // Should fail, nondom isn't allowed as children of dom const _brokenTree2 = {tree}{tree} ~~~~~~ -!!! error TS2741: Property '__domBrand' is missing in type 'Element' but required in type 'Element'. +!!! error TS2741: Property '__domBrand' is missing in type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element' but required in type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element'. !!! related TS2728 tests/cases/conformance/jsx/inline/renderer.d.ts:7:13: '__domBrand' is declared here. ~~~~~~ !!! error TS2322: Type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element' is not assignable to type 'import("tests/cases/conformance/jsx/inline/renderer").dom.JSX.Element'. diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt index df487eb72e..c8490e7e33 100644 --- a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt +++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__predomBrand' is missing in type 'Element' but required in type 'Element'. +tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__predomBrand' is missing in type 'JSX.Element' but required in type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'. ==== tests/cases/conformance/jsx/inline/renderer.d.ts (0 errors) ==== @@ -45,6 +45,6 @@ tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2741: Property '__pre let elem = prerendered; elem = ; // Expect assignability error here ~~~~ -!!! error TS2741: Property '__predomBrand' is missing in type 'Element' but required in type 'Element'. +!!! error TS2741: Property '__predomBrand' is missing in type 'JSX.Element' but required in type 'import("tests/cases/conformance/jsx/inline/renderer2").predom.JSX.Element'. !!! related TS2728 tests/cases/conformance/jsx/inline/renderer2.d.ts:7:13: '__predomBrand' is declared here. \ No newline at end of file diff --git a/tests/baselines/reference/qualify.errors.txt b/tests/baselines/reference/qualify.errors.txt index 932e371180..87d2ad6265 100644 --- a/tests/baselines/reference/qualify.errors.txt +++ b/tests/baselines/reference/qualify.errors.txt @@ -7,7 +7,7 @@ tests/cases/compiler/qualify.ts(47,13): error TS2322: Type 'I4' is not assignabl tests/cases/compiler/qualify.ts(48,13): error TS2322: Type 'I4' is not assignable to type '(k: I3) => void'. Type 'I4' provides no match for the signature '(k: I3): void'. tests/cases/compiler/qualify.ts(49,13): error TS2741: Property 'k' is missing in type 'I4' but required in type '{ k: I3; }'. -tests/cases/compiler/qualify.ts(58,5): error TS2741: Property 'p' is missing in type 'I' but required in type 'I'. +tests/cases/compiler/qualify.ts(58,5): error TS2741: Property 'p' is missing in type 'I' but required in type 'T.I'. ==== tests/cases/compiler/qualify.ts (8 errors) ==== @@ -88,7 +88,7 @@ tests/cases/compiler/qualify.ts(58,5): error TS2741: Property 'p' is missing in var y:I; var x:T.I=y; ~ -!!! error TS2741: Property 'p' is missing in type 'I' but required in type 'I'. +!!! error TS2741: Property 'p' is missing in type 'I' but required in type 'T.I'. !!! related TS2728 tests/cases/compiler/qualify.ts:18:9: 'p' is declared here. \ No newline at end of file diff --git a/tests/cases/compiler/errorWithSameNameType.ts b/tests/cases/compiler/errorWithSameNameType.ts new file mode 100644 index 0000000000..662ae63875 --- /dev/null +++ b/tests/cases/compiler/errorWithSameNameType.ts @@ -0,0 +1,22 @@ +// @filename: a.ts +export interface F { + foo1: number +} + +// @filename: b.ts +export interface F { + foo2: number +} + +// @filename: c.ts +import * as A from './a' +import * as B from './b' + +let a: A.F +let b: B.F + +if (a === b) { + +} + +a = b