Disallow type and interface declarations in statements with blockless bodies (#60183)
This commit is contained in:
Родитель
2e4f2c72db
Коммит
c07da583af
|
@ -46774,6 +46774,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
function checkInterfaceDeclaration(node: InterfaceDeclaration) {
|
||||
// Grammar checking
|
||||
if (!checkGrammarModifiers(node)) checkGrammarInterfaceDeclaration(node);
|
||||
if (!allowBlockDeclarations(node.parent)) {
|
||||
grammarErrorOnNode(node, Diagnostics._0_declarations_can_only_be_declared_inside_a_block, "interface");
|
||||
}
|
||||
|
||||
checkTypeParameters(node.typeParameters);
|
||||
addLazyDiagnostic(() => {
|
||||
|
@ -46817,6 +46820,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
// Grammar checking
|
||||
checkGrammarModifiers(node);
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0);
|
||||
if (!allowBlockDeclarations(node.parent)) {
|
||||
grammarErrorOnNode(node, Diagnostics._0_declarations_can_only_be_declared_inside_a_block, "type");
|
||||
}
|
||||
checkExportsOnMergedDeclarations(node);
|
||||
checkTypeParameters(node.typeParameters);
|
||||
if (node.type.kind === SyntaxKind.IntrinsicKeyword) {
|
||||
|
@ -52051,7 +52057,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
return false;
|
||||
}
|
||||
|
||||
function allowLetAndConstDeclarations(parent: Node): boolean {
|
||||
function allowBlockDeclarations(parent: Node): boolean {
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.IfStatement:
|
||||
case SyntaxKind.DoStatement:
|
||||
|
@ -52062,14 +52068,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
case SyntaxKind.ForOfStatement:
|
||||
return false;
|
||||
case SyntaxKind.LabeledStatement:
|
||||
return allowLetAndConstDeclarations(parent.parent);
|
||||
return allowBlockDeclarations(parent.parent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkGrammarForDisallowedBlockScopedVariableStatement(node: VariableStatement) {
|
||||
if (!allowLetAndConstDeclarations(node.parent)) {
|
||||
if (!allowBlockDeclarations(node.parent)) {
|
||||
const blockScopeKind = getCombinedNodeFlagsCached(node.declarationList) & NodeFlags.BlockScoped;
|
||||
if (blockScopeKind) {
|
||||
const keyword = blockScopeKind === NodeFlags.Let ? "let" :
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
typeAliasDeclarationEmit3.ts(3,14): error TS1156: 'type' declarations can only be declared inside a block.
|
||||
typeAliasDeclarationEmit3.ts(9,14): error TS1156: 'type' declarations can only be declared inside a block.
|
||||
typeAliasDeclarationEmit3.ts(15,14): error TS1156: 'type' declarations can only be declared inside a block.
|
||||
|
||||
|
||||
==== typeAliasDeclarationEmit3.ts (3 errors) ====
|
||||
function f1(): void {
|
||||
for (let i = 0; i < 1; i++)
|
||||
type foo = [];
|
||||
~~~
|
||||
!!! error TS1156: 'type' declarations can only be declared inside a block.
|
||||
console.log('f1');
|
||||
}
|
||||
|
||||
function f2(): void {
|
||||
while (true)
|
||||
type foo = [];
|
||||
~~~
|
||||
!!! error TS1156: 'type' declarations can only be declared inside a block.
|
||||
console.log('f2');
|
||||
}
|
||||
|
||||
function f3(): void {
|
||||
if (true)
|
||||
type foo = [];
|
||||
~~~
|
||||
!!! error TS1156: 'type' declarations can only be declared inside a block.
|
||||
console.log('f3');
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
typeInterfaceDeclarationsInBlockStatements1.ts(4,18): error TS1156: 'type' declarations can only be declared inside a block.
|
||||
typeInterfaceDeclarationsInBlockStatements1.ts(12,21): error TS2304: Cannot find name 's'.
|
||||
typeInterfaceDeclarationsInBlockStatements1.ts(17,15): error TS1156: 'interface' declarations can only be declared inside a block.
|
||||
typeInterfaceDeclarationsInBlockStatements1.ts(29,21): error TS2304: Cannot find name 's'.
|
||||
|
||||
|
||||
==== typeInterfaceDeclarationsInBlockStatements1.ts (4 errors) ====
|
||||
// https://github.com/microsoft/TypeScript/issues/60175
|
||||
|
||||
function f1() {
|
||||
if (true) type s = string;
|
||||
~
|
||||
!!! error TS1156: 'type' declarations can only be declared inside a block.
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
if (true) {
|
||||
type s = string;
|
||||
}
|
||||
console.log("" as s);
|
||||
~
|
||||
!!! error TS2304: Cannot find name 's'.
|
||||
}
|
||||
|
||||
function f3() {
|
||||
if (true)
|
||||
interface s {
|
||||
~
|
||||
!!! error TS1156: 'interface' declarations can only be declared inside a block.
|
||||
length: number;
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
if (true) {
|
||||
interface s {
|
||||
length: number;
|
||||
}
|
||||
}
|
||||
console.log("" as s);
|
||||
~
|
||||
!!! error TS2304: Cannot find name 's'.
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//// [tests/cases/compiler/typeInterfaceDeclarationsInBlockStatements1.ts] ////
|
||||
|
||||
//// [typeInterfaceDeclarationsInBlockStatements1.ts]
|
||||
// https://github.com/microsoft/TypeScript/issues/60175
|
||||
|
||||
function f1() {
|
||||
if (true) type s = string;
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
if (true) {
|
||||
type s = string;
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
if (true)
|
||||
interface s {
|
||||
length: number;
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
if (true) {
|
||||
interface s {
|
||||
length: number;
|
||||
}
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
|
||||
//// [typeInterfaceDeclarationsInBlockStatements1.js]
|
||||
"use strict";
|
||||
// https://github.com/microsoft/TypeScript/issues/60175
|
||||
function f1() {
|
||||
if (true)
|
||||
;
|
||||
console.log("");
|
||||
}
|
||||
function f2() {
|
||||
if (true) {
|
||||
}
|
||||
console.log("");
|
||||
}
|
||||
function f3() {
|
||||
if (true)
|
||||
;
|
||||
console.log("");
|
||||
}
|
||||
function f4() {
|
||||
if (true) {
|
||||
}
|
||||
console.log("");
|
||||
}
|
||||
|
||||
|
||||
//// [typeInterfaceDeclarationsInBlockStatements1.d.ts]
|
||||
declare function f1(): void;
|
||||
declare function f2(): void;
|
||||
declare function f3(): void;
|
||||
declare function f4(): void;
|
|
@ -0,0 +1,67 @@
|
|||
//// [tests/cases/compiler/typeInterfaceDeclarationsInBlockStatements1.ts] ////
|
||||
|
||||
=== typeInterfaceDeclarationsInBlockStatements1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/60175
|
||||
|
||||
function f1() {
|
||||
>f1 : Symbol(f1, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 0, 0))
|
||||
|
||||
if (true) type s = string;
|
||||
>s : Symbol(s, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 3, 11))
|
||||
|
||||
console.log("" as s);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>s : Symbol(s, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 3, 11))
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 5, 1))
|
||||
|
||||
if (true) {
|
||||
type s = string;
|
||||
>s : Symbol(s, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 8, 13))
|
||||
}
|
||||
console.log("" as s);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>s : Symbol(s)
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : Symbol(f3, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 12, 1))
|
||||
|
||||
if (true)
|
||||
interface s {
|
||||
>s : Symbol(s, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 15, 11))
|
||||
|
||||
length: number;
|
||||
>length : Symbol(s.length, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 16, 17))
|
||||
}
|
||||
console.log("" as s);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>s : Symbol(s, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 15, 11))
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : Symbol(f4, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 20, 1))
|
||||
|
||||
if (true) {
|
||||
interface s {
|
||||
>s : Symbol(s, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 23, 13))
|
||||
|
||||
length: number;
|
||||
>length : Symbol(s.length, Decl(typeInterfaceDeclarationsInBlockStatements1.ts, 24, 17))
|
||||
}
|
||||
}
|
||||
console.log("" as s);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>s : Symbol(s)
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
//// [tests/cases/compiler/typeInterfaceDeclarationsInBlockStatements1.ts] ////
|
||||
|
||||
=== typeInterfaceDeclarationsInBlockStatements1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/60175
|
||||
|
||||
function f1() {
|
||||
>f1 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
if (true) type s = string;
|
||||
>true : true
|
||||
> : ^^^^
|
||||
>s : string
|
||||
> : ^^^^^^
|
||||
|
||||
console.log("" as s);
|
||||
>console.log("" as s) : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"" as s : string
|
||||
> : ^^^^^^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
if (true) {
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
type s = string;
|
||||
>s : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
console.log("" as s);
|
||||
>console.log("" as s) : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"" as s : s
|
||||
> : ^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
if (true)
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
interface s {
|
||||
length: number;
|
||||
>length : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
console.log("" as s);
|
||||
>console.log("" as s) : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"" as s : s
|
||||
> : ^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
if (true) {
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
interface s {
|
||||
length: number;
|
||||
>length : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
console.log("" as s);
|
||||
>console.log("" as s) : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>"" as s : s
|
||||
> : ^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/60175
|
||||
|
||||
function f1() {
|
||||
if (true) type s = string;
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
if (true) {
|
||||
type s = string;
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
if (true)
|
||||
interface s {
|
||||
length: number;
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
if (true) {
|
||||
interface s {
|
||||
length: number;
|
||||
}
|
||||
}
|
||||
console.log("" as s);
|
||||
}
|
Загрузка…
Ссылка в новой задаче