Skip to content

Commit e607c8e

Browse files
authored
fix(54760): Report error for 'declare type' followed by newline (#54761)
1 parent ec48ce8 commit e607c8e

6 files changed

+174
-0
lines changed

src/compiler/parser.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7106,11 +7106,17 @@ namespace Parser {
71067106
case SyntaxKind.ProtectedKeyword:
71077107
case SyntaxKind.PublicKeyword:
71087108
case SyntaxKind.ReadonlyKeyword:
7109+
const previousToken = token();
71097110
nextToken();
71107111
// ASI takes effect for this modifier.
71117112
if (scanner.hasPrecedingLineBreak()) {
71127113
return false;
71137114
}
7115+
if (previousToken === SyntaxKind.DeclareKeyword && token() === SyntaxKind.TypeKeyword) {
7116+
// If we see 'declare type', then commit to parsing a type alias. parseTypeAliasDeclaration will
7117+
// report Line_break_not_permitted_here if needed.
7118+
return true;
7119+
}
71147120
continue;
71157121

71167122
case SyntaxKind.GlobalKeyword:
@@ -8107,6 +8113,9 @@ namespace Parser {
81078113

81088114
function parseTypeAliasDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray<ModifierLike> | undefined): TypeAliasDeclaration {
81098115
parseExpected(SyntaxKind.TypeKeyword);
8116+
if (scanner.hasPrecedingLineBreak()) {
8117+
parseErrorAtCurrentToken(Diagnostics.Line_break_not_permitted_here);
8118+
}
81108119
const name = parseIdentifier();
81118120
const typeParameters = parseTypeParameters();
81128121
parseExpected(SyntaxKind.EqualsToken);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
typeAliasDeclareKeywordNewlines.ts(5,1): error TS1142: Line break not permitted here.
2+
3+
4+
==== typeAliasDeclareKeywordNewlines.ts (1 errors) ====
5+
var declare: string, type: number;
6+
7+
// The following is invalid but should declare a type alias named 'T1':
8+
declare type /*unexpected newline*/
9+
T1 = null;
10+
~~
11+
!!! error TS1142: Line break not permitted here.
12+
const t1: T1 = null; // Assert that T1 is the null type.
13+
14+
let T: null;
15+
// The following should use a variable named 'declare', use a variable named
16+
// 'type', and assign to a variable named 'T'.
17+
declare /*ASI*/
18+
type /*ASI*/
19+
T = null;
20+
21+
// The following should use a variable named 'declare' and declare a type alias
22+
// named 'T2':
23+
declare /*ASI*/
24+
type T2 = null;
25+
const t2: T2 = null; // Assert that T2 is the null type.
26+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [tests/cases/compiler/typeAliasDeclareKeywordNewlines.ts] ////
2+
3+
//// [typeAliasDeclareKeywordNewlines.ts]
4+
var declare: string, type: number;
5+
6+
// The following is invalid but should declare a type alias named 'T1':
7+
declare type /*unexpected newline*/
8+
T1 = null;
9+
const t1: T1 = null; // Assert that T1 is the null type.
10+
11+
let T: null;
12+
// The following should use a variable named 'declare', use a variable named
13+
// 'type', and assign to a variable named 'T'.
14+
declare /*ASI*/
15+
type /*ASI*/
16+
T = null;
17+
18+
// The following should use a variable named 'declare' and declare a type alias
19+
// named 'T2':
20+
declare /*ASI*/
21+
type T2 = null;
22+
const t2: T2 = null; // Assert that T2 is the null type.
23+
24+
25+
//// [typeAliasDeclareKeywordNewlines.js]
26+
var declare, type;
27+
var t1 = null; // Assert that T1 is the null type.
28+
var T;
29+
// The following should use a variable named 'declare', use a variable named
30+
// 'type', and assign to a variable named 'T'.
31+
declare; /*ASI*/
32+
type; /*ASI*/
33+
T = null;
34+
// The following should use a variable named 'declare' and declare a type alias
35+
// named 'T2':
36+
declare; /*ASI*/
37+
var t2 = null; // Assert that T2 is the null type.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//// [tests/cases/compiler/typeAliasDeclareKeywordNewlines.ts] ////
2+
3+
=== typeAliasDeclareKeywordNewlines.ts ===
4+
var declare: string, type: number;
5+
>declare : Symbol(declare, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 3))
6+
>type : Symbol(type, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 20))
7+
8+
// The following is invalid but should declare a type alias named 'T1':
9+
declare type /*unexpected newline*/
10+
T1 = null;
11+
>T1 : Symbol(T1, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 34))
12+
13+
const t1: T1 = null; // Assert that T1 is the null type.
14+
>t1 : Symbol(t1, Decl(typeAliasDeclareKeywordNewlines.ts, 5, 5))
15+
>T1 : Symbol(T1, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 34))
16+
17+
let T: null;
18+
>T : Symbol(T, Decl(typeAliasDeclareKeywordNewlines.ts, 7, 3))
19+
20+
// The following should use a variable named 'declare', use a variable named
21+
// 'type', and assign to a variable named 'T'.
22+
declare /*ASI*/
23+
>declare : Symbol(declare, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 3))
24+
25+
type /*ASI*/
26+
>type : Symbol(type, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 20))
27+
28+
T = null;
29+
>T : Symbol(T, Decl(typeAliasDeclareKeywordNewlines.ts, 7, 3))
30+
31+
// The following should use a variable named 'declare' and declare a type alias
32+
// named 'T2':
33+
declare /*ASI*/
34+
>declare : Symbol(declare, Decl(typeAliasDeclareKeywordNewlines.ts, 0, 3))
35+
36+
type T2 = null;
37+
>T2 : Symbol(T2, Decl(typeAliasDeclareKeywordNewlines.ts, 16, 7))
38+
39+
const t2: T2 = null; // Assert that T2 is the null type.
40+
>t2 : Symbol(t2, Decl(typeAliasDeclareKeywordNewlines.ts, 18, 5))
41+
>T2 : Symbol(T2, Decl(typeAliasDeclareKeywordNewlines.ts, 16, 7))
42+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//// [tests/cases/compiler/typeAliasDeclareKeywordNewlines.ts] ////
2+
3+
=== typeAliasDeclareKeywordNewlines.ts ===
4+
var declare: string, type: number;
5+
>declare : string
6+
>type : number
7+
8+
// The following is invalid but should declare a type alias named 'T1':
9+
declare type /*unexpected newline*/
10+
T1 = null;
11+
>T1 : null
12+
13+
const t1: T1 = null; // Assert that T1 is the null type.
14+
>t1 : null
15+
16+
let T: null;
17+
>T : null
18+
19+
// The following should use a variable named 'declare', use a variable named
20+
// 'type', and assign to a variable named 'T'.
21+
declare /*ASI*/
22+
>declare : string
23+
24+
type /*ASI*/
25+
>type : number
26+
27+
T = null;
28+
>T = null : null
29+
>T : null
30+
31+
// The following should use a variable named 'declare' and declare a type alias
32+
// named 'T2':
33+
declare /*ASI*/
34+
>declare : string
35+
36+
type T2 = null;
37+
>T2 : null
38+
39+
const t2: T2 = null; // Assert that T2 is the null type.
40+
>t2 : null
41+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var declare: string, type: number;
2+
3+
// The following is invalid but should declare a type alias named 'T1':
4+
declare type /*unexpected newline*/
5+
T1 = null;
6+
const t1: T1 = null; // Assert that T1 is the null type.
7+
8+
let T: null;
9+
// The following should use a variable named 'declare', use a variable named
10+
// 'type', and assign to a variable named 'T'.
11+
declare /*ASI*/
12+
type /*ASI*/
13+
T = null;
14+
15+
// The following should use a variable named 'declare' and declare a type alias
16+
// named 'T2':
17+
declare /*ASI*/
18+
type T2 = null;
19+
const t2: T2 = null; // Assert that T2 is the null type.

0 commit comments

Comments
 (0)