diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f4d8c99c471..01b3a047d1d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13048,7 +13048,7 @@ namespace ts { node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration).exclamationToken || declaration.flags & NodeFlags.Ambient; - const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) : + const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) : type === autoType || type === autoArrayType ? undefinedType : getOptionalType(type); const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized); diff --git a/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.errors.txt b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.errors.txt new file mode 100644 index 00000000000..b2fea589cb1 --- /dev/null +++ b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.errors.txt @@ -0,0 +1,92 @@ +tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts(6,8): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. + Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts(16,7): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. + Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts(21,7): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. + Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts(31,8): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. + Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts(45,10): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. + Type 'undefined' is not assignable to type 'number'. +tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts(53,11): error TS2345: Argument of type 'number | null' is not assignable to parameter of type 'number | undefined'. + Type 'null' is not assignable to type 'number | undefined'. + + +==== tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts (6 errors) ==== + // https://github.com/Microsoft/TypeScript/issues/17080 + + declare function f(a:number,b:number): void; + + function func1( {a, b}: {a: number, b?: number} = {a: 1, b: 2} ) { + f(a, b) + ~ +!!! error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'undefined' is not assignable to type 'number'. + // error + } + + function func2( {a, b = 3}: {a: number, b?:number} = {a: 1,b: 2} ) { + f(a, b) + // no error + } + + function func3( {a, b}: {a: number, b?: number} = {a: 1} ) { + f(a,b) + ~ +!!! error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'undefined' is not assignable to type 'number'. + // error + } + + function func4( {a: {b, c}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { + f(b,c) + ~ +!!! error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'undefined' is not assignable to type 'number'. + // error + } + + function func5({a: {b, c = 4}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { + f(b, c) + // no error + } + + function func6( {a: {b, c} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1,c: 2}, d: 3} ) { + f(b, c) + ~ +!!! error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'undefined' is not assignable to type 'number'. + // error + } + + function func7( {a: {b, c = 6} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1, c: 2}, d: 3} ) { + f(b, c) + // no error + } + + interface Foo { + readonly bar?: number; + } + + function performFoo({ bar }: Foo = {}) { + useBar(bar); + ~~~ +!!! error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. +!!! error TS2345: Type 'undefined' is not assignable to type 'number'. + } + + declare function useBar(bar: number): void; + + performFoo(); + + function performFoo2({ bar = null }: Foo = {}) { + useBar2(bar); + ~~~ +!!! error TS2345: Argument of type 'number | null' is not assignable to parameter of type 'number | undefined'. +!!! error TS2345: Type 'null' is not assignable to type 'number | undefined'. + } + + declare function useBar2(bar: number | undefined): void; + + performFoo2(); + \ No newline at end of file diff --git a/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.js b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.js new file mode 100644 index 00000000000..642f00a4f50 --- /dev/null +++ b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.js @@ -0,0 +1,108 @@ +//// [optionalParameterInDestructuringWithInitializer.ts] +// https://github.com/Microsoft/TypeScript/issues/17080 + +declare function f(a:number,b:number): void; + +function func1( {a, b}: {a: number, b?: number} = {a: 1, b: 2} ) { + f(a, b) + // error +} + +function func2( {a, b = 3}: {a: number, b?:number} = {a: 1,b: 2} ) { + f(a, b) + // no error +} + +function func3( {a, b}: {a: number, b?: number} = {a: 1} ) { + f(a,b) + // error +} + +function func4( {a: {b, c}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { + f(b,c) + // error +} + +function func5({a: {b, c = 4}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { + f(b, c) + // no error +} + +function func6( {a: {b, c} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1,c: 2}, d: 3} ) { + f(b, c) + // error +} + +function func7( {a: {b, c = 6} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1, c: 2}, d: 3} ) { + f(b, c) + // no error +} + +interface Foo { + readonly bar?: number; +} + +function performFoo({ bar }: Foo = {}) { + useBar(bar); +} + +declare function useBar(bar: number): void; + +performFoo(); + +function performFoo2({ bar = null }: Foo = {}) { + useBar2(bar); +} + +declare function useBar2(bar: number | undefined): void; + +performFoo2(); + + +//// [optionalParameterInDestructuringWithInitializer.js] +// https://github.com/Microsoft/TypeScript/issues/17080 +function func1(_a) { + var _b = _a === void 0 ? { a: 1, b: 2 } : _a, a = _b.a, b = _b.b; + f(a, b); + // error +} +function func2(_a) { + var _b = _a === void 0 ? { a: 1, b: 2 } : _a, a = _b.a, _c = _b.b, b = _c === void 0 ? 3 : _c; + f(a, b); + // no error +} +function func3(_a) { + var _b = _a === void 0 ? { a: 1 } : _a, a = _b.a, b = _b.b; + f(a, b); + // error +} +function func4(_a) { + var _b = _a === void 0 ? { a: { b: 1, c: 2 }, d: 3 } : _a, _c = _b.a, b = _c.b, c = _c.c, d = _b.d; + f(b, c); + // error +} +function func5(_a) { + var _b = _a === void 0 ? { a: { b: 1, c: 2 }, d: 3 } : _a, _c = _b.a, b = _c.b, _d = _c.c, c = _d === void 0 ? 4 : _d, d = _b.d; + f(b, c); + // no error +} +function func6(_a) { + var _b = _a === void 0 ? { a: { b: 1, c: 2 }, d: 3 } : _a, _c = _b.a, _d = _c === void 0 ? { b: 4, c: 5 } : _c, b = _d.b, c = _d.c, d = _b.d; + f(b, c); + // error +} +function func7(_a) { + var _b = _a === void 0 ? { a: { b: 1, c: 2 }, d: 3 } : _a, _c = _b.a, _d = _c === void 0 ? { b: 4, c: 5 } : _c, b = _d.b, _e = _d.c, c = _e === void 0 ? 6 : _e, d = _b.d; + f(b, c); + // no error +} +function performFoo(_a) { + var bar = (_a === void 0 ? {} : _a).bar; + useBar(bar); +} +performFoo(); +function performFoo2(_a) { + var _b = (_a === void 0 ? {} : _a).bar, bar = _b === void 0 ? null : _b; + useBar2(bar); +} +performFoo2(); diff --git a/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.symbols b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.symbols new file mode 100644 index 00000000000..6d4cf484d92 --- /dev/null +++ b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.symbols @@ -0,0 +1,195 @@ +=== tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts === +// https://github.com/Microsoft/TypeScript/issues/17080 + +declare function f(a:number,b:number): void; +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 2, 19)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 2, 28)) + +function func1( {a, b}: {a: number, b?: number} = {a: 1, b: 2} ) { +>func1 : Symbol(func1, Decl(optionalParameterInDestructuringWithInitializer.ts, 2, 44)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 17)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 19)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 25)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 35)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 51)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 56)) + + f(a, b) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 17)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 4, 19)) + + // error +} + +function func2( {a, b = 3}: {a: number, b?:number} = {a: 1,b: 2} ) { +>func2 : Symbol(func2, Decl(optionalParameterInDestructuringWithInitializer.ts, 7, 1)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 17)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 19)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 29)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 39)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 54)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 59)) + + f(a, b) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 17)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 9, 19)) + + // no error +} + +function func3( {a, b}: {a: number, b?: number} = {a: 1} ) { +>func3 : Symbol(func3, Decl(optionalParameterInDestructuringWithInitializer.ts, 12, 1)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 17)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 19)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 25)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 35)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 51)) + + f(a,b) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 17)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 14, 19)) + + // error +} + +function func4( {a: {b, c}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { +>func4 : Symbol(func4, Decl(optionalParameterInDestructuringWithInitializer.ts, 17, 1)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 33)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 21)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 23)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 27)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 33)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 37)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 47)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 59)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 73)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 77)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 82)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 88)) + + f(b,c) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 21)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 19, 23)) + + // error +} + +function func5({a: {b, c = 4}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { +>func5 : Symbol(func5, Decl(optionalParameterInDestructuringWithInitializer.ts, 22, 1)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 36)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 20)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 22)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 30)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 36)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 40)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 50)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 62)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 76)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 80)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 85)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 91)) + + f(b, c) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 20)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 24, 22)) + + // no error +} + +function func6( {a: {b, c} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1,c: 2}, d: 3} ) { +>func6 : Symbol(func6, Decl(optionalParameterInDestructuringWithInitializer.ts, 27, 1)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 48)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 21)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 23)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 30)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 35)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 42)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 48)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 52)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 62)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 75)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 90)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 94)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 99)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 105)) + + f(b, c) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 21)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 29, 23)) + + // error +} + +function func7( {a: {b, c = 6} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1, c: 2}, d: 3} ) { +>func7 : Symbol(func7, Decl(optionalParameterInDestructuringWithInitializer.ts, 32, 1)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 52)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 21)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 23)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 34)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 39)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 46)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 52)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 56)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 66)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 79)) +>a : Symbol(a, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 94)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 98)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 103)) +>d : Symbol(d, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 110)) + + f(b, c) +>f : Symbol(f, Decl(optionalParameterInDestructuringWithInitializer.ts, 0, 0)) +>b : Symbol(b, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 21)) +>c : Symbol(c, Decl(optionalParameterInDestructuringWithInitializer.ts, 34, 23)) + + // no error +} + +interface Foo { +>Foo : Symbol(Foo, Decl(optionalParameterInDestructuringWithInitializer.ts, 37, 1)) + + readonly bar?: number; +>bar : Symbol(Foo.bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 39, 15)) +} + +function performFoo({ bar }: Foo = {}) { +>performFoo : Symbol(performFoo, Decl(optionalParameterInDestructuringWithInitializer.ts, 41, 1)) +>bar : Symbol(bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 43, 21)) +>Foo : Symbol(Foo, Decl(optionalParameterInDestructuringWithInitializer.ts, 37, 1)) + + useBar(bar); +>useBar : Symbol(useBar, Decl(optionalParameterInDestructuringWithInitializer.ts, 45, 1)) +>bar : Symbol(bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 43, 21)) +} + +declare function useBar(bar: number): void; +>useBar : Symbol(useBar, Decl(optionalParameterInDestructuringWithInitializer.ts, 45, 1)) +>bar : Symbol(bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 47, 24)) + +performFoo(); +>performFoo : Symbol(performFoo, Decl(optionalParameterInDestructuringWithInitializer.ts, 41, 1)) + +function performFoo2({ bar = null }: Foo = {}) { +>performFoo2 : Symbol(performFoo2, Decl(optionalParameterInDestructuringWithInitializer.ts, 49, 13)) +>bar : Symbol(bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 51, 22)) +>Foo : Symbol(Foo, Decl(optionalParameterInDestructuringWithInitializer.ts, 37, 1)) + + useBar2(bar); +>useBar2 : Symbol(useBar2, Decl(optionalParameterInDestructuringWithInitializer.ts, 53, 1)) +>bar : Symbol(bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 51, 22)) +} + +declare function useBar2(bar: number | undefined): void; +>useBar2 : Symbol(useBar2, Decl(optionalParameterInDestructuringWithInitializer.ts, 53, 1)) +>bar : Symbol(bar, Decl(optionalParameterInDestructuringWithInitializer.ts, 55, 25)) + +performFoo2(); +>performFoo2 : Symbol(performFoo2, Decl(optionalParameterInDestructuringWithInitializer.ts, 49, 13)) + diff --git a/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.types b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.types new file mode 100644 index 00000000000..26110e71051 --- /dev/null +++ b/tests/baselines/reference/optionalParameterInDestructuringWithInitializer.types @@ -0,0 +1,246 @@ +=== tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts === +// https://github.com/Microsoft/TypeScript/issues/17080 + +declare function f(a:number,b:number): void; +>f : (a: number, b: number) => void +>a : number +>b : number + +function func1( {a, b}: {a: number, b?: number} = {a: 1, b: 2} ) { +>func1 : ({ a, b }?: { a: number; b?: number | undefined; }) => void +>a : number +>b : number | undefined +>a : number +>b : number | undefined +>{a: 1, b: 2} : { a: number; b: number; } +>a : number +>1 : 1 +>b : number +>2 : 2 + + f(a, b) +>f(a, b) : void +>f : (a: number, b: number) => void +>a : number +>b : number | undefined + + // error +} + +function func2( {a, b = 3}: {a: number, b?:number} = {a: 1,b: 2} ) { +>func2 : ({ a, b }?: { a: number; b?: number | undefined; }) => void +>a : number +>b : number +>3 : 3 +>a : number +>b : number | undefined +>{a: 1,b: 2} : { a: number; b: number; } +>a : number +>1 : 1 +>b : number +>2 : 2 + + f(a, b) +>f(a, b) : void +>f : (a: number, b: number) => void +>a : number +>b : number + + // no error +} + +function func3( {a, b}: {a: number, b?: number} = {a: 1} ) { +>func3 : ({ a, b }?: { a: number; b?: number | undefined; }) => void +>a : number +>b : number | undefined +>a : number +>b : number | undefined +>{a: 1} : { a: number; } +>a : number +>1 : 1 + + f(a,b) +>f(a,b) : void +>f : (a: number, b: number) => void +>a : number +>b : number | undefined + + // error +} + +function func4( {a: {b, c}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { +>func4 : ({ a: { b, c }, d }?: { a: { b: number; c?: number | undefined; }; d: number; }) => void +>a : any +>b : number +>c : number | undefined +>d : number +>a : { b: number; c?: number | undefined; } +>b : number +>c : number | undefined +>d : number +>{a: {b: 1,c: 2},d: 3} : { a: { b: number; c: number; }; d: number; } +>a : { b: number; c: number; } +>{b: 1,c: 2} : { b: number; c: number; } +>b : number +>1 : 1 +>c : number +>2 : 2 +>d : number +>3 : 3 + + f(b,c) +>f(b,c) : void +>f : (a: number, b: number) => void +>b : number +>c : number | undefined + + // error +} + +function func5({a: {b, c = 4}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { +>func5 : ({ a: { b, c }, d }?: { a: { b: number; c?: number | undefined; }; d: number; }) => void +>a : any +>b : number +>c : number +>4 : 4 +>d : number +>a : { b: number; c?: number | undefined; } +>b : number +>c : number | undefined +>d : number +>{a: {b: 1,c: 2},d: 3} : { a: { b: number; c: number; }; d: number; } +>a : { b: number; c: number; } +>{b: 1,c: 2} : { b: number; c: number; } +>b : number +>1 : 1 +>c : number +>2 : 2 +>d : number +>3 : 3 + + f(b, c) +>f(b, c) : void +>f : (a: number, b: number) => void +>b : number +>c : number + + // no error +} + +function func6( {a: {b, c} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1,c: 2}, d: 3} ) { +>func6 : ({ a: { b, c }, d }?: { a: { b: number; c?: number | undefined; }; d: number; }) => void +>a : any +>b : number +>c : number | undefined +>{b: 4, c: 5} : { b: number; c: number; } +>b : number +>4 : 4 +>c : number +>5 : 5 +>d : number +>a : { b: number; c?: number | undefined; } +>b : number +>c : number | undefined +>d : number +>{a: {b: 1,c: 2}, d: 3} : { a: { b: number; c: number; }; d: number; } +>a : { b: number; c: number; } +>{b: 1,c: 2} : { b: number; c: number; } +>b : number +>1 : 1 +>c : number +>2 : 2 +>d : number +>3 : 3 + + f(b, c) +>f(b, c) : void +>f : (a: number, b: number) => void +>b : number +>c : number | undefined + + // error +} + +function func7( {a: {b, c = 6} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1, c: 2}, d: 3} ) { +>func7 : ({ a: { b, c }, d }?: { a: { b: number; c?: number | undefined; }; d: number; }) => void +>a : any +>b : number +>c : number +>6 : 6 +>{b: 4, c: 5} : { b: number; c?: number; } +>b : number +>4 : 4 +>c : number +>5 : 5 +>d : number +>a : { b: number; c?: number | undefined; } +>b : number +>c : number | undefined +>d : number +>{a: {b: 1, c: 2}, d: 3} : { a: { b: number; c: number; }; d: number; } +>a : { b: number; c: number; } +>{b: 1, c: 2} : { b: number; c: number; } +>b : number +>1 : 1 +>c : number +>2 : 2 +>d : number +>3 : 3 + + f(b, c) +>f(b, c) : void +>f : (a: number, b: number) => void +>b : number +>c : number + + // no error +} + +interface Foo { +>Foo : Foo + + readonly bar?: number; +>bar : number | undefined +} + +function performFoo({ bar }: Foo = {}) { +>performFoo : ({ bar }?: Foo) => void +>bar : number | undefined +>Foo : Foo +>{} : {} + + useBar(bar); +>useBar(bar) : void +>useBar : (bar: number) => void +>bar : number | undefined +} + +declare function useBar(bar: number): void; +>useBar : (bar: number) => void +>bar : number + +performFoo(); +>performFoo() : void +>performFoo : ({ bar }?: Foo) => void + +function performFoo2({ bar = null }: Foo = {}) { +>performFoo2 : ({ bar }?: Foo) => void +>bar : number | null +>null : null +>Foo : Foo +>{} : {} + + useBar2(bar); +>useBar2(bar) : void +>useBar2 : (bar: number | undefined) => void +>bar : number | null +} + +declare function useBar2(bar: number | undefined): void; +>useBar2 : (bar: number | undefined) => void +>bar : number | undefined + +performFoo2(); +>performFoo2() : void +>performFoo2 : ({ bar }?: Foo) => void + diff --git a/tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts b/tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts new file mode 100644 index 00000000000..d3ebd99efa1 --- /dev/null +++ b/tests/cases/compiler/optionalParameterInDestructuringWithInitializer.ts @@ -0,0 +1,59 @@ +// @strictNullChecks: true +// https://github.com/Microsoft/TypeScript/issues/17080 + +declare function f(a:number,b:number): void; + +function func1( {a, b}: {a: number, b?: number} = {a: 1, b: 2} ) { + f(a, b) + // error +} + +function func2( {a, b = 3}: {a: number, b?:number} = {a: 1,b: 2} ) { + f(a, b) + // no error +} + +function func3( {a, b}: {a: number, b?: number} = {a: 1} ) { + f(a,b) + // error +} + +function func4( {a: {b, c}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { + f(b,c) + // error +} + +function func5({a: {b, c = 4}, d}: {a: {b: number,c?: number},d: number} = {a: {b: 1,c: 2},d: 3} ) { + f(b, c) + // no error +} + +function func6( {a: {b, c} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1,c: 2}, d: 3} ) { + f(b, c) + // error +} + +function func7( {a: {b, c = 6} = {b: 4, c: 5}, d}: {a: {b: number, c?: number}, d: number} = {a: {b: 1, c: 2}, d: 3} ) { + f(b, c) + // no error +} + +interface Foo { + readonly bar?: number; +} + +function performFoo({ bar }: Foo = {}) { + useBar(bar); +} + +declare function useBar(bar: number): void; + +performFoo(); + +function performFoo2({ bar = null }: Foo = {}) { + useBar2(bar); +} + +declare function useBar2(bar: number | undefined): void; + +performFoo2();