diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 05e53154056..576f8566e26 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25119,7 +25119,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isInAmbientOrTypeNode(node: Node): boolean { - return !!(node.flags & NodeFlags.Ambient || findAncestor(node, n => isInterfaceDeclaration(n) || isTypeLiteralNode(n))); + return !!(node.flags & NodeFlags.Ambient || findAncestor(node, n => isInterfaceDeclaration(n) || isTypeAliasDeclaration(n) || isTypeLiteralNode(n))); } // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers @@ -40653,6 +40653,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // For a binding pattern, validate the initializer and exit if (isBindingPattern(node.name)) { + if (isInAmbientOrTypeNode(node)) { + return; + } const needCheckInitializer = hasOnlyExpressionInitializer(node) && node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement; const needCheckWidenedType = !some(node.name.elements, not(isOmittedExpression)); if (needCheckInitializer || needCheckWidenedType) { diff --git a/tests/baselines/reference/emptyOptionalBindingPatternInDeclarationSignature.symbols b/tests/baselines/reference/emptyOptionalBindingPatternInDeclarationSignature.symbols new file mode 100644 index 00000000000..2649d618170 --- /dev/null +++ b/tests/baselines/reference/emptyOptionalBindingPatternInDeclarationSignature.symbols @@ -0,0 +1,83 @@ +=== tests/cases/compiler/emptyOptionalBindingPatternInDeclarationSignature.ts === +// #50791 + +declare function fn1({}?: { x: string }): void; +>fn1 : Symbol(fn1, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 0, 0)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 2, 27)) + +declare function fn2({ x }?: { x: string }): void; +>fn2 : Symbol(fn2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 2, 47)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 3, 22)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 3, 30)) + +declare function fn3([]?: [ x: string ]): void; +>fn3 : Symbol(fn3, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 3, 50)) + +declare function fn4([ x ]?: [ x: string ]): void; +>fn4 : Symbol(fn4, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 4, 47)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 5, 22)) + +declare class C1 { +>C1 : Symbol(C1, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 5, 50)) + + method({}?: { x: string }): void +>method : Symbol(C1.method, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 7, 18)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 8, 17)) + + static method2({}?: { x: string }): void +>method2 : Symbol(C1.method2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 8, 36)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 9, 25)) + + static field: ({}?: { x: string }) => void +>field : Symbol(C1.field, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 9, 44)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 11, 25)) + + static field2: ({}?: { x: string }) => void +>field2 : Symbol(C1.field2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 11, 46)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 12, 26)) +} + +interface I1 { +>I1 : Symbol(I1, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 13, 1)) + + method({}?: { x: string }): void +>method : Symbol(I1.method, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 15, 14)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 16, 17)) + + method2: ({}?: { x: string }) => void +>method2 : Symbol(I1.method2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 16, 36)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 17, 20)) +} + +type T1 = ({}?: { x: string }) => void +>T1 : Symbol(T1, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 18, 1)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 20, 17)) + +type T2 = { +>T2 : Symbol(T2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 20, 38)) + + method({}?: { x: string }): void +>method : Symbol(method, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 22, 11)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 23, 17)) + + method2: ({}?: { x: string }) => void +>method2 : Symbol(method2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 23, 36)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 24, 20)) +} + +declare const val1: ({}?: { x: string }) => void +>val1 : Symbol(val1, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 27, 13)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 27, 27)) + +declare const val2: { +>val2 : Symbol(val2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 29, 13)) + + method({}?: { x: string }): void +>method : Symbol(method, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 29, 21)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 30, 17)) + + method2: ({}?: { x: string }) => void +>method2 : Symbol(method2, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 30, 36)) +>x : Symbol(x, Decl(emptyOptionalBindingPatternInDeclarationSignature.ts, 31, 20)) +} + diff --git a/tests/baselines/reference/emptyOptionalBindingPatternInDeclarationSignature.types b/tests/baselines/reference/emptyOptionalBindingPatternInDeclarationSignature.types new file mode 100644 index 00000000000..f1bca05d429 --- /dev/null +++ b/tests/baselines/reference/emptyOptionalBindingPatternInDeclarationSignature.types @@ -0,0 +1,81 @@ +=== tests/cases/compiler/emptyOptionalBindingPatternInDeclarationSignature.ts === +// #50791 + +declare function fn1({}?: { x: string }): void; +>fn1 : ({}?: { x: string;}) => void +>x : string + +declare function fn2({ x }?: { x: string }): void; +>fn2 : ({ x }?: { x: string;}) => void +>x : string +>x : string + +declare function fn3([]?: [ x: string ]): void; +>fn3 : ([]?: [x: string]) => void + +declare function fn4([ x ]?: [ x: string ]): void; +>fn4 : ([x]?: [x: string]) => void +>x : string + +declare class C1 { +>C1 : C1 + + method({}?: { x: string }): void +>method : ({}?: { x: string;}) => void +>x : string + + static method2({}?: { x: string }): void +>method2 : ({}?: { x: string;}) => void +>x : string + + static field: ({}?: { x: string }) => void +>field : ({}?: { x: string;}) => void +>x : string + + static field2: ({}?: { x: string }) => void +>field2 : ({}?: { x: string;}) => void +>x : string +} + +interface I1 { + method({}?: { x: string }): void +>method : ({}?: { x: string;}) => void +>x : string + + method2: ({}?: { x: string }) => void +>method2 : ({}?: { x: string;}) => void +>x : string +} + +type T1 = ({}?: { x: string }) => void +>T1 : ({}?: { x: string;}) => void +>x : string + +type T2 = { +>T2 : { method({}?: { x: string;}): void; method2: ({}?: { x: string;}) => void; } + + method({}?: { x: string }): void +>method : ({}?: { x: string;}) => void +>x : string + + method2: ({}?: { x: string }) => void +>method2 : ({}?: { x: string;}) => void +>x : string +} + +declare const val1: ({}?: { x: string }) => void +>val1 : ({}?: { x: string;}) => void +>x : string + +declare const val2: { +>val2 : { method({}?: { x: string;}): void; method2: ({}?: { x: string;}) => void; } + + method({}?: { x: string }): void +>method : ({}?: { x: string;}) => void +>x : string + + method2: ({}?: { x: string }) => void +>method2 : ({}?: { x: string;}) => void +>x : string +} + diff --git a/tests/cases/compiler/emptyOptionalBindingPatternInDeclarationSignature.ts b/tests/cases/compiler/emptyOptionalBindingPatternInDeclarationSignature.ts new file mode 100644 index 00000000000..f15fedfd6f3 --- /dev/null +++ b/tests/cases/compiler/emptyOptionalBindingPatternInDeclarationSignature.ts @@ -0,0 +1,36 @@ +// @strict: true +// @noEmit: true + +// #50791 + +declare function fn1({}?: { x: string }): void; +declare function fn2({ x }?: { x: string }): void; +declare function fn3([]?: [ x: string ]): void; +declare function fn4([ x ]?: [ x: string ]): void; + +declare class C1 { + method({}?: { x: string }): void + static method2({}?: { x: string }): void + + static field: ({}?: { x: string }) => void + static field2: ({}?: { x: string }) => void +} + +interface I1 { + method({}?: { x: string }): void + method2: ({}?: { x: string }) => void +} + +type T1 = ({}?: { x: string }) => void + +type T2 = { + method({}?: { x: string }): void + method2: ({}?: { x: string }) => void +} + +declare const val1: ({}?: { x: string }) => void + +declare const val2: { + method({}?: { x: string }): void + method2: ({}?: { x: string }) => void +}