From 39f04bf99722881bec27b2750b00933cd53a3239 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 21 Apr 2023 12:44:31 +0300 Subject: [PATCH 1/2] fix(53933): forbid using initializer in destructured parameter in function type --- src/compiler/checker.ts | 2 +- .../defaultValueInFunctionTypes.errors.txt | 14 ++++++++++---- .../reference/defaultValueInFunctionTypes.js | 5 ++++- .../reference/defaultValueInFunctionTypes.symbols | 13 +++++++++---- .../reference/defaultValueInFunctionTypes.types | 6 ++++++ .../cases/compiler/defaultValueInFunctionTypes.ts | 4 +++- 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8a5c0045e5481..f09d2393f4a53 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -40928,7 +40928,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { forEach(node.name.elements, checkSourceElement); } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body - if (isParameter(node) && node.initializer && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { + if (hasInitializer(node) && isParameterDeclaration(node) && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); return; } diff --git a/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt b/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt index 5544b9caae0fd..d531650beea60 100644 --- a/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt +++ b/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt @@ -1,11 +1,17 @@ -tests/cases/compiler/defaultValueInFunctionTypes.ts(1,9): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. -tests/cases/compiler/defaultValueInFunctionTypes.ts(2,11): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. +tests/cases/compiler/defaultValueInFunctionTypes.ts(1,15): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. +tests/cases/compiler/defaultValueInFunctionTypes.ts(3,9): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. +tests/cases/compiler/defaultValueInFunctionTypes.ts(4,11): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. -==== tests/cases/compiler/defaultValueInFunctionTypes.ts (2 errors) ==== +==== tests/cases/compiler/defaultValueInFunctionTypes.ts (3 errors) ==== + type Foo = ({ first = 0 }: { first?: number }) => unknown; + ~~~~~ +!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. + var x: (a: number = 1) => number; ~~~~~~~~~~~~~ !!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. var y = <(a : string = "") => any>(undefined) ~~~~~~~~~~~~~~~ -!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. \ No newline at end of file +!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. + \ No newline at end of file diff --git a/tests/baselines/reference/defaultValueInFunctionTypes.js b/tests/baselines/reference/defaultValueInFunctionTypes.js index c3f2bf6082957..986a8efd6aa31 100644 --- a/tests/baselines/reference/defaultValueInFunctionTypes.js +++ b/tests/baselines/reference/defaultValueInFunctionTypes.js @@ -1,6 +1,9 @@ //// [defaultValueInFunctionTypes.ts] +type Foo = ({ first = 0 }: { first?: number }) => unknown; + var x: (a: number = 1) => number; -var y = <(a : string = "") => any>(undefined) +var y = <(a : string = "") => any>(undefined) + //// [defaultValueInFunctionTypes.js] var x; diff --git a/tests/baselines/reference/defaultValueInFunctionTypes.symbols b/tests/baselines/reference/defaultValueInFunctionTypes.symbols index ce4f8c3d4d062..92483eea17113 100644 --- a/tests/baselines/reference/defaultValueInFunctionTypes.symbols +++ b/tests/baselines/reference/defaultValueInFunctionTypes.symbols @@ -1,10 +1,15 @@ === tests/cases/compiler/defaultValueInFunctionTypes.ts === +type Foo = ({ first = 0 }: { first?: number }) => unknown; +>Foo : Symbol(Foo, Decl(defaultValueInFunctionTypes.ts, 0, 0)) +>first : Symbol(first, Decl(defaultValueInFunctionTypes.ts, 0, 13)) +>first : Symbol(first, Decl(defaultValueInFunctionTypes.ts, 0, 28)) + var x: (a: number = 1) => number; ->x : Symbol(x, Decl(defaultValueInFunctionTypes.ts, 0, 3)) ->a : Symbol(a, Decl(defaultValueInFunctionTypes.ts, 0, 8)) +>x : Symbol(x, Decl(defaultValueInFunctionTypes.ts, 2, 3)) +>a : Symbol(a, Decl(defaultValueInFunctionTypes.ts, 2, 8)) var y = <(a : string = "") => any>(undefined) ->y : Symbol(y, Decl(defaultValueInFunctionTypes.ts, 1, 3)) ->a : Symbol(a, Decl(defaultValueInFunctionTypes.ts, 1, 10)) +>y : Symbol(y, Decl(defaultValueInFunctionTypes.ts, 3, 3)) +>a : Symbol(a, Decl(defaultValueInFunctionTypes.ts, 3, 10)) >undefined : Symbol(undefined) diff --git a/tests/baselines/reference/defaultValueInFunctionTypes.types b/tests/baselines/reference/defaultValueInFunctionTypes.types index 99af03c60f460..7d4e534336087 100644 --- a/tests/baselines/reference/defaultValueInFunctionTypes.types +++ b/tests/baselines/reference/defaultValueInFunctionTypes.types @@ -1,4 +1,10 @@ === tests/cases/compiler/defaultValueInFunctionTypes.ts === +type Foo = ({ first = 0 }: { first?: number }) => unknown; +>Foo : ({ first }: { first?: number; }) => unknown +>first : number +>0 : 0 +>first : number + var x: (a: number = 1) => number; >x : (a?: number) => number >a : number diff --git a/tests/cases/compiler/defaultValueInFunctionTypes.ts b/tests/cases/compiler/defaultValueInFunctionTypes.ts index fd9229a210448..cae244be77dc1 100644 --- a/tests/cases/compiler/defaultValueInFunctionTypes.ts +++ b/tests/cases/compiler/defaultValueInFunctionTypes.ts @@ -1,2 +1,4 @@ +type Foo = ({ first = 0 }: { first?: number }) => unknown; + var x: (a: number = 1) => number; -var y = <(a : string = "") => any>(undefined) \ No newline at end of file +var y = <(a : string = "") => any>(undefined) From 54cfb55f3ddab8ec47c1dea45913ad2f0bb48893 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 30 Oct 2023 21:05:48 +0200 Subject: [PATCH 2/2] remove hasInitializer helper usage --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 87b217809ad0c..c3eaf0d00b1ec 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -41050,7 +41050,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { forEach(node.name.elements, checkSourceElement); } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body - if (hasInitializer(node) && isParameterDeclaration(node) && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { + if (node.initializer && isParameterDeclaration(node) && nodeIsMissing((getContainingFunction(node) as FunctionLikeDeclaration).body)) { error(node, Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation); return; }