mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Improve error message for computed enums (#37790)
* Add error message for computed enums * Add test case for computed enums * Accept baselines * Fix returned value when error
This commit is contained in:
parent
92cd3ae299
commit
06e05f25e1
@ -33676,7 +33676,13 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// Only here do we need to check that the initializer is assignable to the enum type.
|
||||
checkTypeAssignableTo(checkExpression(initializer), getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
|
||||
const source = checkExpression(initializer);
|
||||
if (!isTypeAssignableToKind(source, TypeFlags.NumberLike)) {
|
||||
error(initializer, Diagnostics.Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead, typeToString(source));
|
||||
}
|
||||
else {
|
||||
checkTypeAssignableTo(source, getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
||||
|
||||
@ -5737,5 +5737,9 @@
|
||||
"The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some.": {
|
||||
"category": "Error",
|
||||
"code": 18032
|
||||
},
|
||||
"Only numeric enums can have computed members, but this expression has type '{0}'. If you do not need exhaustiveness checks, consider using an object literal instead.": {
|
||||
"category": "Error",
|
||||
"code": 18033
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(2,1): error TS2410: The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(30,9): error TS2322: Type '() => number' is not assignable to type 'E'.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(30,9): error TS18033: Only numeric enums can have computed members, but this expression has type '() => number'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(31,16): error TS2332: 'this' cannot be referenced in current location.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(43,5): error TS2410: The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(71,13): error TS2322: Type '() => number' is not assignable to type 'E'.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(71,13): error TS18033: Only numeric enums can have computed members, but this expression has type '() => number'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(72,20): error TS2332: 'this' cannot be referenced in current location.
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(72,20): e
|
||||
enum E {
|
||||
x = () => 4, // Error expected
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '() => number' is not assignable to type 'E'.
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type '() => number'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
y = (() => this).length // error, can't use this in enum
|
||||
~~~~
|
||||
!!! error TS2332: 'this' cannot be referenced in current location.
|
||||
@ -87,7 +87,7 @@ tests/cases/conformance/expressions/functions/arrowFunctionContexts.ts(72,20): e
|
||||
enum E {
|
||||
x = () => 4, // Error expected
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '() => number' is not assignable to type 'E'.
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type '() => number'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
y = (() => this).length
|
||||
~~~~
|
||||
!!! error TS2332: 'this' cannot be referenced in current location.
|
||||
|
||||
@ -2,28 +2,30 @@ tests/cases/conformance/enums/enumErrors.ts(2,6): error TS2431: Enum name cannot
|
||||
tests/cases/conformance/enums/enumErrors.ts(3,6): error TS2431: Enum name cannot be 'number'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(4,6): error TS2431: Enum name cannot be 'string'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(5,6): error TS2431: Enum name cannot be 'boolean'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(9,9): error TS2322: Type 'Number' is not assignable to type 'E5'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(26,9): error TS2322: Type 'true' is not assignable to type 'E11'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(27,9): error TS2322: Type 'Date' is not assignable to type 'E11'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(28,9): error TS2322: Type 'Window & typeof globalThis' is not assignable to type 'E11'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(29,9): error TS2322: Type '{}' is not assignable to type 'E11'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(35,9): error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
tests/cases/conformance/enums/enumErrors.ts(9,9): error TS18033: Only numeric enums can have computed members, but this expression has type 'Number'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/enums/enumErrors.ts(26,9): error TS18033: Only numeric enums can have computed members, but this expression has type 'true'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/enums/enumErrors.ts(27,9): error TS18033: Only numeric enums can have computed members, but this expression has type 'Date'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/enums/enumErrors.ts(28,9): error TS18033: Only numeric enums can have computed members, but this expression has type 'Window & typeof globalThis'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/enums/enumErrors.ts(29,9): error TS18033: Only numeric enums can have computed members, but this expression has type '{}'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/enums/enumErrors.ts(30,9): error TS18033: Only numeric enums can have computed members, but this expression has type 'string'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
tests/cases/conformance/enums/enumErrors.ts(36,9): error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
tests/cases/conformance/enums/enumErrors.ts(37,9): error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
tests/cases/conformance/enums/enumErrors.ts(38,9): error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
tests/cases/conformance/enums/enumErrors.ts(46,18): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(47,24): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(47,26): error TS2452: An enum member cannot have a numeric name.
|
||||
tests/cases/conformance/enums/enumErrors.ts(48,28): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(48,30): error TS2452: An enum member cannot have a numeric name.
|
||||
tests/cases/conformance/enums/enumErrors.ts(48,31): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(51,16): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(51,22): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(51,30): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(51,33): error TS2452: An enum member cannot have a numeric name.
|
||||
tests/cases/conformance/enums/enumErrors.ts(39,9): error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
tests/cases/conformance/enums/enumErrors.ts(40,9): error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
tests/cases/conformance/enums/enumErrors.ts(48,18): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(49,24): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(49,26): error TS2452: An enum member cannot have a numeric name.
|
||||
tests/cases/conformance/enums/enumErrors.ts(50,28): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(50,30): error TS2452: An enum member cannot have a numeric name.
|
||||
tests/cases/conformance/enums/enumErrors.ts(50,31): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(53,16): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(53,22): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(53,30): error TS1357: An enum member name must be followed by a ',', '=', or '}'.
|
||||
tests/cases/conformance/enums/enumErrors.ts(53,33): error TS2452: An enum member cannot have a numeric name.
|
||||
|
||||
|
||||
==== tests/cases/conformance/enums/enumErrors.ts (23 errors) ====
|
||||
==== tests/cases/conformance/enums/enumErrors.ts (25 errors) ====
|
||||
// Enum named with PredefinedTypes
|
||||
enum any { }
|
||||
~~~
|
||||
@ -42,7 +44,7 @@ tests/cases/conformance/enums/enumErrors.ts(51,33): error TS2452: An enum member
|
||||
enum E5 {
|
||||
C = new Number(30)
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'Number' is not assignable to type 'E5'.
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type 'Number'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
}
|
||||
|
||||
enum E9 {
|
||||
@ -61,16 +63,19 @@ tests/cases/conformance/enums/enumErrors.ts(51,33): error TS2452: An enum member
|
||||
enum E11 {
|
||||
A = true,
|
||||
~~~~
|
||||
!!! error TS2322: Type 'true' is not assignable to type 'E11'.
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type 'true'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
B = new Date(),
|
||||
~~~~~~~~~~
|
||||
!!! error TS2322: Type 'Date' is not assignable to type 'E11'.
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type 'Date'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
C = window,
|
||||
~~~~~~
|
||||
!!! error TS2322: Type 'Window & typeof globalThis' is not assignable to type 'E11'.
|
||||
D = {}
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type 'Window & typeof globalThis'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
D = {},
|
||||
~~
|
||||
!!! error TS2322: Type '{}' is not assignable to type 'E11'.
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type '{}'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
E = (() => 'foo')(),
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS18033: Only numeric enums can have computed members, but this expression has type 'string'. If you do not need exhaustiveness checks, consider using an object literal instead.
|
||||
}
|
||||
|
||||
// Enum with string valued member and computed member initializers
|
||||
@ -87,6 +92,9 @@ tests/cases/conformance/enums/enumErrors.ts(51,33): error TS2452: An enum member
|
||||
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
E = 1 + 1,
|
||||
~~~~~
|
||||
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
F = (() => 'foo')(),
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2553: Computed values are not permitted in an enum with string valued members.
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,8 @@ enum E11 {
|
||||
A = true,
|
||||
B = new Date(),
|
||||
C = window,
|
||||
D = {}
|
||||
D = {},
|
||||
E = (() => 'foo')(),
|
||||
}
|
||||
|
||||
// Enum with string valued member and computed member initializers
|
||||
@ -37,6 +38,7 @@ enum E12 {
|
||||
C = window,
|
||||
D = {},
|
||||
E = 1 + 1,
|
||||
F = (() => 'foo')(),
|
||||
}
|
||||
|
||||
// Enum with incorrect syntax
|
||||
@ -90,6 +92,7 @@ var E11;
|
||||
E11[E11["B"] = new Date()] = "B";
|
||||
E11[E11["C"] = window] = "C";
|
||||
E11[E11["D"] = {}] = "D";
|
||||
E11[E11["E"] = (function () { return 'foo'; })()] = "E";
|
||||
})(E11 || (E11 = {}));
|
||||
// Enum with string valued member and computed member initializers
|
||||
var E12;
|
||||
@ -99,6 +102,7 @@ var E12;
|
||||
E12[E12["C"] = 0] = "C";
|
||||
E12[E12["D"] = 0] = "D";
|
||||
E12[E12["E"] = 0] = "E";
|
||||
E12[E12["F"] = 0] = "F";
|
||||
})(E12 || (E12 = {}));
|
||||
// Enum with incorrect syntax
|
||||
var E13;
|
||||
|
||||
@ -65,62 +65,68 @@ enum E11 {
|
||||
>C : Symbol(E11.C, Decl(enumErrors.ts, 26, 19))
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
D = {}
|
||||
D = {},
|
||||
>D : Symbol(E11.D, Decl(enumErrors.ts, 27, 15))
|
||||
|
||||
E = (() => 'foo')(),
|
||||
>E : Symbol(E11.E, Decl(enumErrors.ts, 28, 11))
|
||||
}
|
||||
|
||||
// Enum with string valued member and computed member initializers
|
||||
enum E12 {
|
||||
>E12 : Symbol(E12, Decl(enumErrors.ts, 29, 1))
|
||||
>E12 : Symbol(E12, Decl(enumErrors.ts, 30, 1))
|
||||
|
||||
A = '',
|
||||
>A : Symbol(E12.A, Decl(enumErrors.ts, 32, 10))
|
||||
>A : Symbol(E12.A, Decl(enumErrors.ts, 33, 10))
|
||||
|
||||
B = new Date(),
|
||||
>B : Symbol(E12.B, Decl(enumErrors.ts, 33, 11))
|
||||
>B : Symbol(E12.B, Decl(enumErrors.ts, 34, 11))
|
||||
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --))
|
||||
|
||||
C = window,
|
||||
>C : Symbol(E12.C, Decl(enumErrors.ts, 34, 19))
|
||||
>C : Symbol(E12.C, Decl(enumErrors.ts, 35, 19))
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
D = {},
|
||||
>D : Symbol(E12.D, Decl(enumErrors.ts, 35, 15))
|
||||
>D : Symbol(E12.D, Decl(enumErrors.ts, 36, 15))
|
||||
|
||||
E = 1 + 1,
|
||||
>E : Symbol(E12.E, Decl(enumErrors.ts, 36, 11))
|
||||
>E : Symbol(E12.E, Decl(enumErrors.ts, 37, 11))
|
||||
|
||||
F = (() => 'foo')(),
|
||||
>F : Symbol(E12.F, Decl(enumErrors.ts, 38, 14))
|
||||
}
|
||||
|
||||
// Enum with incorrect syntax
|
||||
enum E13 {
|
||||
>E13 : Symbol(E13, Decl(enumErrors.ts, 38, 1))
|
||||
>E13 : Symbol(E13, Decl(enumErrors.ts, 40, 1))
|
||||
|
||||
postComma,
|
||||
>postComma : Symbol(E13.postComma, Decl(enumErrors.ts, 41, 10))
|
||||
>postComma : Symbol(E13.postComma, Decl(enumErrors.ts, 43, 10))
|
||||
|
||||
postValueComma = 1,
|
||||
>postValueComma : Symbol(E13.postValueComma, Decl(enumErrors.ts, 42, 14))
|
||||
>postValueComma : Symbol(E13.postValueComma, Decl(enumErrors.ts, 44, 14))
|
||||
|
||||
postSemicolon;
|
||||
>postSemicolon : Symbol(E13.postSemicolon, Decl(enumErrors.ts, 43, 23))
|
||||
>postSemicolon : Symbol(E13.postSemicolon, Decl(enumErrors.ts, 45, 23))
|
||||
|
||||
postColonValueComma: 2,
|
||||
>postColonValueComma : Symbol(E13.postColonValueComma, Decl(enumErrors.ts, 45, 18))
|
||||
>2 : Symbol(E13[2], Decl(enumErrors.ts, 46, 24))
|
||||
>postColonValueComma : Symbol(E13.postColonValueComma, Decl(enumErrors.ts, 47, 18))
|
||||
>2 : Symbol(E13[2], Decl(enumErrors.ts, 48, 24))
|
||||
|
||||
postColonValueSemicolon: 3;
|
||||
>postColonValueSemicolon : Symbol(E13.postColonValueSemicolon, Decl(enumErrors.ts, 46, 27))
|
||||
>3 : Symbol(E13[3], Decl(enumErrors.ts, 47, 28))
|
||||
>postColonValueSemicolon : Symbol(E13.postColonValueSemicolon, Decl(enumErrors.ts, 48, 27))
|
||||
>3 : Symbol(E13[3], Decl(enumErrors.ts, 49, 28))
|
||||
|
||||
};
|
||||
|
||||
enum E14 { a, b: any "hello" += 1, c, d}
|
||||
>E14 : Symbol(E14, Decl(enumErrors.ts, 48, 2))
|
||||
>a : Symbol(E14.a, Decl(enumErrors.ts, 50, 10))
|
||||
>b : Symbol(E14.b, Decl(enumErrors.ts, 50, 13))
|
||||
>any : Symbol(E14.any, Decl(enumErrors.ts, 50, 16))
|
||||
>"hello" : Symbol(E14["hello"], Decl(enumErrors.ts, 50, 20))
|
||||
>1 : Symbol(E14[1], Decl(enumErrors.ts, 50, 31))
|
||||
>c : Symbol(E14.c, Decl(enumErrors.ts, 50, 34))
|
||||
>d : Symbol(E14.d, Decl(enumErrors.ts, 50, 37))
|
||||
>E14 : Symbol(E14, Decl(enumErrors.ts, 50, 2))
|
||||
>a : Symbol(E14.a, Decl(enumErrors.ts, 52, 10))
|
||||
>b : Symbol(E14.b, Decl(enumErrors.ts, 52, 13))
|
||||
>any : Symbol(E14.any, Decl(enumErrors.ts, 52, 16))
|
||||
>"hello" : Symbol(E14["hello"], Decl(enumErrors.ts, 52, 20))
|
||||
>1 : Symbol(E14[1], Decl(enumErrors.ts, 52, 31))
|
||||
>c : Symbol(E14.c, Decl(enumErrors.ts, 52, 34))
|
||||
>d : Symbol(E14.d, Decl(enumErrors.ts, 52, 37))
|
||||
|
||||
|
||||
@ -69,9 +69,16 @@ enum E11 {
|
||||
>C : E11
|
||||
>window : Window & typeof globalThis
|
||||
|
||||
D = {}
|
||||
D = {},
|
||||
>D : E11
|
||||
>{} : {}
|
||||
|
||||
E = (() => 'foo')(),
|
||||
>E : E11
|
||||
>(() => 'foo')() : string
|
||||
>(() => 'foo') : () => string
|
||||
>() => 'foo' : () => string
|
||||
>'foo' : "foo"
|
||||
}
|
||||
|
||||
// Enum with string valued member and computed member initializers
|
||||
@ -100,6 +107,13 @@ enum E12 {
|
||||
>1 + 1 : number
|
||||
>1 : 1
|
||||
>1 : 1
|
||||
|
||||
F = (() => 'foo')(),
|
||||
>F : E12.B
|
||||
>(() => 'foo')() : string
|
||||
>(() => 'foo') : () => string
|
||||
>() => 'foo' : () => string
|
||||
>'foo' : "foo"
|
||||
}
|
||||
|
||||
// Enum with incorrect syntax
|
||||
|
||||
@ -26,7 +26,8 @@ enum E11 {
|
||||
A = true,
|
||||
B = new Date(),
|
||||
C = window,
|
||||
D = {}
|
||||
D = {},
|
||||
E = (() => 'foo')(),
|
||||
}
|
||||
|
||||
// Enum with string valued member and computed member initializers
|
||||
@ -36,6 +37,7 @@ enum E12 {
|
||||
C = window,
|
||||
D = {},
|
||||
E = 1 + 1,
|
||||
F = (() => 'foo')(),
|
||||
}
|
||||
|
||||
// Enum with incorrect syntax
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user