diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bc9906f2054..d8cbbe5f758 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4229,7 +4229,7 @@ namespace ts { /** Return the inferred type for a binding element */ function getTypeForBindingElement(declaration: BindingElement): Type { const pattern = declaration.parent; - const parentType = getTypeForBindingElementParent(pattern.parent); + let parentType = getTypeForBindingElementParent(pattern.parent); // If parent has the unknown (error) type, then so does this binding element if (parentType === unknownType) { return unknownType; @@ -4271,6 +4271,10 @@ namespace ts { // or otherwise the type of the string index signature. const text = getTextOfPropertyName(name); + // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation + if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { + parentType = getNonNullableType(parentType); + } const declaredType = getTypeOfPropertyOfType(parentType, text); type = declaredType && getFlowTypeOfReference(declaration, declaredType) || isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) || diff --git a/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.js b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.js new file mode 100644 index 00000000000..8a6a602d6d7 --- /dev/null +++ b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.js @@ -0,0 +1,11 @@ +//// [initializedParameterBeforeNonoptionalNotOptional.ts] +export declare function foo({a}?: { + a?: string; +}): void; +export declare function foo2({a}: { + a?: string | undefined; +} | undefined, b: string): void; + +//// [initializedParameterBeforeNonoptionalNotOptional.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.symbols b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.symbols new file mode 100644 index 00000000000..9e91e2bd3aa --- /dev/null +++ b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/index.d.ts === +export declare function foo({a}?: { +>foo : Symbol(foo, Decl(index.d.ts, 0, 0)) +>a : Symbol(a, Decl(index.d.ts, 0, 29)) + + a?: string; +>a : Symbol(a, Decl(index.d.ts, 0, 35)) + +}): void; +export declare function foo2({a}: { +>foo2 : Symbol(foo2, Decl(index.d.ts, 2, 9)) +>a : Symbol(a, Decl(index.d.ts, 3, 30)) + + a?: string | undefined; +>a : Symbol(a, Decl(index.d.ts, 3, 35)) + +} | undefined, b: string): void; +>b : Symbol(b, Decl(index.d.ts, 5, 14)) + +export declare function foo3({a, b: {c}}: { +>foo3 : Symbol(foo3, Decl(index.d.ts, 5, 32)) +>a : Symbol(a, Decl(index.d.ts, 6, 30)) +>c : Symbol(c, Decl(index.d.ts, 6, 37)) + + a?: string | undefined; +>a : Symbol(a, Decl(index.d.ts, 6, 43)) + + b?: {c?: string | undefined;} | undefined; +>b : Symbol(b, Decl(index.d.ts, 7, 27)) +>c : Symbol(c, Decl(index.d.ts, 8, 9)) + +} | undefined, b: string): void; +>b : Symbol(b, Decl(index.d.ts, 9, 14)) + diff --git a/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types new file mode 100644 index 00000000000..798b5268337 --- /dev/null +++ b/tests/baselines/reference/initializedParameterBeforeNonoptionalNotOptional.types @@ -0,0 +1,35 @@ +=== tests/cases/compiler/index.d.ts === +export declare function foo({a}?: { +>foo : ({ a }?: { a?: string | undefined; } | undefined) => void +>a : string | undefined + + a?: string; +>a : string | undefined + +}): void; +export declare function foo2({a}: { +>foo2 : ({ a }: { a?: string | undefined; } | undefined, b: string) => void +>a : string | undefined + + a?: string | undefined; +>a : string | undefined + +} | undefined, b: string): void; +>b : string + +export declare function foo3({a, b: {c}}: { +>foo3 : ({ a, b: { c } }: { a?: string | undefined; b?: { c?: string | undefined; } | undefined; } | undefined, b: string) => void +>a : string | undefined +>b : any +>c : string | undefined + + a?: string | undefined; +>a : string | undefined + + b?: {c?: string | undefined;} | undefined; +>b : { c?: string | undefined; } | undefined +>c : string | undefined + +} | undefined, b: string): void; +>b : string + diff --git a/tests/cases/compiler/initializedParameterBeforeNonoptionalNotOptional.ts b/tests/cases/compiler/initializedParameterBeforeNonoptionalNotOptional.ts new file mode 100644 index 00000000000..327849ae80e --- /dev/null +++ b/tests/cases/compiler/initializedParameterBeforeNonoptionalNotOptional.ts @@ -0,0 +1,12 @@ +// @strict: true +// @filename: index.d.ts +export declare function foo({a}?: { + a?: string; +}): void; +export declare function foo2({a}: { + a?: string | undefined; +} | undefined, b: string): void; +export declare function foo3({a, b: {c}}: { + a?: string | undefined; + b?: {c?: string | undefined;} | undefined; +} | undefined, b: string): void; \ No newline at end of file