improve error message when type have same name (#27065)

* improve error message when type have same name

* fix lint and function name

* update test case

* accept baseline
This commit is contained in:
Wenlu Wang 2019-04-23 14:56:03 -05:00 committed by Ryan Cavanaugh
parent a3c852db9b
commit bd178746de
12 changed files with 203 additions and 23 deletions

View file

@ -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(

View file

@ -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;

View file

@ -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.

View file

@ -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.

View file

@ -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;

View file

@ -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))

View file

@ -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

View file

@ -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();
~~~~~~~~~~~~~~

View file

@ -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 = <h></h>; // 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[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{props.children}</p>;
@ -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 = <DOMSFC x={1} y={2}>{tree}{tree}</DOMSFC>
~~~~~~
!!! 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'.

View file

@ -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 = <h></h>; // 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.

View file

@ -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.

View file

@ -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