mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-14 15:33:32 -06:00
Fixed false positive errors in empty optional binding patterns in declaration signatures (#50816)
This commit is contained in:
parent
9c5b09cd21
commit
080f9c1c3f
@ -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) {
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user