Skip to content

Commit 7e0ddf4

Browse files
committed
Error on new type-ish names named undefined
1 parent e0ae9be commit 7e0ddf4

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/compiler/parser.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3923,6 +3923,9 @@ namespace Parser {
39233923
const pos = getNodePos();
39243924
const modifiers = parseModifiers(/*allowDecorators*/ false, /*permitConstAsModifier*/ true);
39253925
const name = parseIdentifier();
3926+
if (name.escapedText === "undefined") {
3927+
parseErrorAtRange(name, Diagnostics.Type_parameter_name_cannot_be_0, "undefined");
3928+
}
39263929
let constraint: TypeNode | undefined;
39273930
let expression: Expression | undefined;
39283931
if (parseOptional(SyntaxKind.ExtendsKeyword)) {
@@ -4369,6 +4372,9 @@ namespace Parser {
43694372
function parseMappedTypeParameter() {
43704373
const pos = getNodePos();
43714374
const name = parseIdentifierName();
4375+
if (name.escapedText === "undefined") {
4376+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
4377+
}
43724378
parseExpected(SyntaxKind.InKeyword);
43734379
const type = parseType();
43744380
return finishNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, type, /*defaultType*/ undefined), pos);
@@ -4733,6 +4739,9 @@ namespace Parser {
47334739
function parseTypeParameterOfInferType(): TypeParameterDeclaration {
47344740
const pos = getNodePos();
47354741
const name = parseIdentifier();
4742+
if (name.escapedText === "undefined") {
4743+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
4744+
}
47364745
const constraint = tryParse(tryParseConstraintOfInferType);
47374746
const node = factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, constraint);
47384747
return finishNode(node, pos);
@@ -8097,6 +8106,9 @@ namespace Parser {
80978106

80988107
// We don't parse the name here in await context, instead we will report a grammar error in the checker.
80998108
const name = parseNameOfClassDeclarationOrExpression();
8109+
if (name?.escapedText === "undefined") {
8110+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
8111+
}
81008112
const typeParameters = parseTypeParameters();
81018113
if (some(modifiers, isExportModifier)) setAwaitContext(/*value*/ true);
81028114
const heritageClauses = parseHeritageClauses();
@@ -8179,6 +8191,9 @@ namespace Parser {
81798191
function parseInterfaceDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray<ModifierLike> | undefined): InterfaceDeclaration {
81808192
parseExpected(SyntaxKind.InterfaceKeyword);
81818193
const name = parseIdentifier();
8194+
if (name.escapedText === "undefined") {
8195+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
8196+
}
81828197
const typeParameters = parseTypeParameters();
81838198
const heritageClauses = parseHeritageClauses();
81848199
const members = parseObjectTypeMembers();
@@ -8192,6 +8207,9 @@ namespace Parser {
81928207
parseErrorAtCurrentToken(Diagnostics.Line_break_not_permitted_here);
81938208
}
81948209
const name = parseIdentifier();
8210+
if (name.escapedText === "undefined") {
8211+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
8212+
}
81958213
const typeParameters = parseTypeParameters();
81968214
parseExpected(SyntaxKind.EqualsToken);
81978215
const type = token() === SyntaxKind.IntrinsicKeyword && tryParse(parseKeywordAndNoDot) || parseType();
@@ -8215,6 +8233,9 @@ namespace Parser {
82158233
function parseEnumDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray<ModifierLike> | undefined): EnumDeclaration {
82168234
parseExpected(SyntaxKind.EnumKeyword);
82178235
const name = parseIdentifier();
8236+
if (name.escapedText === "undefined") {
8237+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
8238+
}
82188239
let members;
82198240
if (parseExpected(SyntaxKind.OpenBraceToken)) {
82208241
members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember));
@@ -8245,6 +8266,9 @@ namespace Parser {
82458266
// propagate the 'Namespace' flag across the names if set.
82468267
const namespaceFlag = flags & NodeFlags.Namespace;
82478268
const name = flags & NodeFlags.NestedNamespace ? parseIdentifierName() : parseIdentifier();
8269+
if (name.escapedText === "undefined") {
8270+
parseErrorAtRange(name, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "undefined");
8271+
}
82488272
const body = parseOptional(SyntaxKind.DotToken)
82498273
? parseModuleOrNamespaceDeclaration(getNodePos(), /*hasJSDoc*/ false, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) as NamespaceDeclaration
82508274
: parseModuleBlock();

tests/baselines/reference/undefinedTypeAssignment1.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
undefinedTypeAssignment1.ts(1,5): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
12
undefinedTypeAssignment1.ts(1,6): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
23

34

4-
==== undefinedTypeAssignment1.ts (1 errors) ====
5+
==== undefinedTypeAssignment1.ts (2 errors) ====
56
type undefined = string;
7+
~~~~~~~~~~
8+
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
69
~~~~~~~~~
710
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
811
function p(undefined = "wat") {

tests/baselines/reference/undefinedTypeAssignment4.errors.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1+
undefinedTypeAssignment4.ts(1,6): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
12
undefinedTypeAssignment4.ts(1,7): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
3+
undefinedTypeAssignment4.ts(4,10): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
24
undefinedTypeAssignment4.ts(4,11): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
5+
undefinedTypeAssignment4.ts(7,10): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
36
undefinedTypeAssignment4.ts(7,11): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
47

58

6-
==== undefinedTypeAssignment4.ts (3 errors) ====
9+
==== undefinedTypeAssignment4.ts (6 errors) ====
710
class undefined {
11+
~~~~~~~~~~
12+
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
813
~~~~~~~~~
914
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
1015
foo: string;
1116
}
1217
interface undefined {
18+
~~~~~~~~~~
19+
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
1320
~~~~~~~~~
1421
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
1522
member: number;
1623
}
1724
namespace undefined {
25+
~~~~~~~~~~
26+
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
1827
~~~~~~~~~
1928
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
2029
export var x = 42;

0 commit comments

Comments
 (0)