diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e911d7fe7d2a3..c3bda292ae9f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9552,7 +9552,7 @@ namespace ts { // contextual type or, if the element itself is a binding pattern, with the type implied by that binding // pattern. const contextualType = isBindingPattern(element.name) ? getTypeFromBindingPattern(element.name, /*includePatternInType*/ true, /*reportErrors*/ false) : unknownType; - return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, CheckMode.Normal, contextualType))); + return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, reportErrors ? CheckMode.Normal : CheckMode.SkipContextSensitive, contextualType))); } if (isBindingPattern(element.name)) { return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); @@ -9692,21 +9692,22 @@ namespace ts { } } - function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type { + function getTypeOfVariableOrParameterOrProperty(symbol: Symbol, checkMode?: CheckMode): Type { const links = getSymbolLinks(symbol); - if (!links.type) { - const type = getTypeOfVariableOrParameterOrPropertyWorker(symbol); + let result = links.type; + if (!result) { + result = getTypeOfVariableOrParameterOrPropertyWorker(symbol, checkMode); // For a contextually typed parameter it is possible that a type has already // been assigned (in assignTypeToParameterAndFixTypeParameters), and we want // to preserve this type. - if (!links.type) { - links.type = type; + if (!links.type && !(checkMode && checkMode !== CheckMode.Normal)) { + links.type = result; } } - return links.type; + return result; } - function getTypeOfVariableOrParameterOrPropertyWorker(symbol: Symbol): Type { + function getTypeOfVariableOrParameterOrPropertyWorker(symbol: Symbol, checkMode?: CheckMode): Type { // Handle prototype property if (symbol.flags & SymbolFlags.Prototype) { return getTypeOfPrototypeProperty(symbol); @@ -9759,6 +9760,10 @@ namespace ts { if (symbol.flags & SymbolFlags.ValueModule && !(symbol.flags & SymbolFlags.Assignment)) { return getTypeOfFuncClassEnumModule(symbol); } + + if (checkMode && checkMode !== CheckMode.Normal) { + return anyType; + } return reportCircularityError(symbol); } let type: Type; @@ -9826,6 +9831,10 @@ namespace ts { if (symbol.flags & SymbolFlags.ValueModule && !(symbol.flags & SymbolFlags.Assignment)) { return getTypeOfFuncClassEnumModule(symbol); } + + if (checkMode && checkMode !== CheckMode.Normal) { + return anyType; + } return reportCircularityError(symbol); } return type; @@ -10073,7 +10082,7 @@ namespace ts { return getTypeOfSymbol(symbol); } - function getTypeOfSymbol(symbol: Symbol): Type { + function getTypeOfSymbol(symbol: Symbol, checkMode?: CheckMode): Type { const checkFlags = getCheckFlags(symbol); if (checkFlags & CheckFlags.DeferredType) { return getTypeOfSymbolWithDeferredType(symbol); @@ -10088,7 +10097,7 @@ namespace ts { return getTypeOfReverseMappedSymbol(symbol as ReverseMappedSymbol); } if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) { - return getTypeOfVariableOrParameterOrProperty(symbol); + return getTypeOfVariableOrParameterOrProperty(symbol, checkMode); } if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) { return getTypeOfFuncClassEnumModule(symbol); @@ -25858,7 +25867,7 @@ namespace ts { } } - function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier) { + function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier, checkMode?: CheckMode) { const declaration = symbol.valueDeclaration; if (declaration) { // If we have a non-rest binding element with no initializer declared as a const variable or a const-like @@ -25938,7 +25947,7 @@ namespace ts { } } } - return getTypeOfSymbol(symbol); + return getTypeOfSymbol(symbol, checkMode); } function checkIdentifier(node: Identifier, checkMode: CheckMode | undefined): Type { @@ -26026,7 +26035,7 @@ namespace ts { checkNestedBlockScopedBinding(node, symbol); - let type = getNarrowedTypeOfSymbol(localOrExportSymbol, node); + let type = getNarrowedTypeOfSymbol(localOrExportSymbol, node, checkMode); const assignmentKind = getAssignmentTargetKind(node); if (assignmentKind) { diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types index 5a0e03dda6e56..260cc6ba513b1 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment3.types @@ -1,15 +1,15 @@ === tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts === const [a, b = a] = [1]; // ok ->a : any ->b : any ->a : any +>a : number +>b : number +>a : number >[1] : [number] >1 : 1 const [c, d = c, e = e] = [1]; // error for e = e ->c : any ->d : any ->c : any +>c : number +>d : number +>c : number >e : any >e : any >[1] : [number] diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.js b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.js new file mode 100644 index 0000000000000..f0a4c81cceccb --- /dev/null +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.js @@ -0,0 +1,36 @@ +//// [destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts] +// To be inferred as `number` +function f1() { + const [a1, b1 = a1] = [1]; + const [a2, b2 = 1 + a2] = [1]; +} + +// To be inferred as `string` +function f2() { + const [a1, b1 = a1] = ['hi']; + const [a2, b2 = a2 + '!'] = ['hi']; +} + +// To be inferred as `string | number` +function f3() { + const [a1, b1 = a1] = ['hi', 1]; + const [a2, b2 = a2 + '!'] = ['hi', 1]; +} + + +//// [destructuringArrayBindingPatternAndAssignment5SiblingInitializer.js] +// To be inferred as `number` +function f1() { + var _a = [1], a1 = _a[0], _b = _a[1], b1 = _b === void 0 ? a1 : _b; + var _c = [1], a2 = _c[0], _d = _c[1], b2 = _d === void 0 ? 1 + a2 : _d; +} +// To be inferred as `string` +function f2() { + var _a = ['hi'], a1 = _a[0], _b = _a[1], b1 = _b === void 0 ? a1 : _b; + var _c = ['hi'], a2 = _c[0], _d = _c[1], b2 = _d === void 0 ? a2 + '!' : _d; +} +// To be inferred as `string | number` +function f3() { + var _a = ['hi', 1], a1 = _a[0], _b = _a[1], b1 = _b === void 0 ? a1 : _b; + var _c = ['hi', 1], a2 = _c[0], _d = _c[1], b2 = _d === void 0 ? a2 + '!' : _d; +} diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.symbols b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.symbols new file mode 100644 index 0000000000000..349b2c2f028f9 --- /dev/null +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.symbols @@ -0,0 +1,46 @@ +=== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts === +// To be inferred as `number` +function f1() { +>f1 : Symbol(f1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 0, 0)) + + const [a1, b1 = a1] = [1]; +>a1 : Symbol(a1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 2, 11)) +>b1 : Symbol(b1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 2, 14)) +>a1 : Symbol(a1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 2, 11)) + + const [a2, b2 = 1 + a2] = [1]; +>a2 : Symbol(a2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 3, 11)) +>b2 : Symbol(b2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 3, 14)) +>a2 : Symbol(a2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 3, 11)) +} + +// To be inferred as `string` +function f2() { +>f2 : Symbol(f2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 4, 1)) + + const [a1, b1 = a1] = ['hi']; +>a1 : Symbol(a1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 8, 11)) +>b1 : Symbol(b1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 8, 14)) +>a1 : Symbol(a1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 8, 11)) + + const [a2, b2 = a2 + '!'] = ['hi']; +>a2 : Symbol(a2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 9, 11)) +>b2 : Symbol(b2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 9, 14)) +>a2 : Symbol(a2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 9, 11)) +} + +// To be inferred as `string | number` +function f3() { +>f3 : Symbol(f3, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 10, 1)) + + const [a1, b1 = a1] = ['hi', 1]; +>a1 : Symbol(a1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 14, 11)) +>b1 : Symbol(b1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 14, 14)) +>a1 : Symbol(a1, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 14, 11)) + + const [a2, b2 = a2 + '!'] = ['hi', 1]; +>a2 : Symbol(a2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 15, 11)) +>b2 : Symbol(b2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 15, 14)) +>a2 : Symbol(a2, Decl(destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts, 15, 11)) +} + diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.types b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.types new file mode 100644 index 0000000000000..63bb82b0a4e81 --- /dev/null +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.types @@ -0,0 +1,66 @@ +=== tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts === +// To be inferred as `number` +function f1() { +>f1 : () => void + + const [a1, b1 = a1] = [1]; +>a1 : number +>b1 : number +>a1 : number +>[1] : [number] +>1 : 1 + + const [a2, b2 = 1 + a2] = [1]; +>a2 : number +>b2 : number +>1 + a2 : number +>1 : 1 +>a2 : number +>[1] : [number] +>1 : 1 +} + +// To be inferred as `string` +function f2() { +>f2 : () => void + + const [a1, b1 = a1] = ['hi']; +>a1 : string +>b1 : string +>a1 : string +>['hi'] : [string] +>'hi' : "hi" + + const [a2, b2 = a2 + '!'] = ['hi']; +>a2 : string +>b2 : string +>a2 + '!' : string +>a2 : string +>'!' : "!" +>['hi'] : [string] +>'hi' : "hi" +} + +// To be inferred as `string | number` +function f3() { +>f3 : () => void + + const [a1, b1 = a1] = ['hi', 1]; +>a1 : string +>b1 : string | number +>a1 : string +>['hi', 1] : [string, number] +>'hi' : "hi" +>1 : 1 + + const [a2, b2 = a2 + '!'] = ['hi', 1]; +>a2 : string +>b2 : string | number +>a2 + '!' : string +>a2 : string +>'!' : "!" +>['hi', 1] : [string, number] +>'hi' : "hi" +>1 : 1 +} + diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.js b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.js new file mode 100644 index 0000000000000..0fd21679b7610 --- /dev/null +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.js @@ -0,0 +1,36 @@ +//// [destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts] +// To be inferred as `number` +function f1() { + const { a1, b1 = a1 } = { a1: 1 }; + const { a2, b2 = 1 + a2 } = { a2: 1 }; +} + +// To be inferred as `string` +function f2() { + const { a1, b1 = a1 } = { a1: 'hi' }; + const { a2, b2 = a2 + '!' } = { a2: 'hi' }; +} + +// To be inferred as `string | number` +function f3() { + const { a1, b1 = a1 } = { a1: 'hi', b1: 1 }; + const { a2, b2 = a2 + '!' } = { a2: 'hi', b2: 1 }; +} + + +//// [destructuringObjectBindingPatternAndAssignment9SiblingInitializer.js] +// To be inferred as `number` +function f1() { + var _a = { a1: 1 }, a1 = _a.a1, _b = _a.b1, b1 = _b === void 0 ? a1 : _b; + var _c = { a2: 1 }, a2 = _c.a2, _d = _c.b2, b2 = _d === void 0 ? 1 + a2 : _d; +} +// To be inferred as `string` +function f2() { + var _a = { a1: 'hi' }, a1 = _a.a1, _b = _a.b1, b1 = _b === void 0 ? a1 : _b; + var _c = { a2: 'hi' }, a2 = _c.a2, _d = _c.b2, b2 = _d === void 0 ? a2 + '!' : _d; +} +// To be inferred as `string | number` +function f3() { + var _a = { a1: 'hi', b1: 1 }, a1 = _a.a1, _b = _a.b1, b1 = _b === void 0 ? a1 : _b; + var _c = { a2: 'hi', b2: 1 }, a2 = _c.a2, _d = _c.b2, b2 = _d === void 0 ? a2 + '!' : _d; +} diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.symbols b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.symbols new file mode 100644 index 0000000000000..03e5f95101df9 --- /dev/null +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts === +// To be inferred as `number` +function f1() { +>f1 : Symbol(f1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 0, 0)) + + const { a1, b1 = a1 } = { a1: 1 }; +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 2, 11)) +>b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 2, 15)) +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 2, 11)) +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 2, 29)) + + const { a2, b2 = 1 + a2 } = { a2: 1 }; +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 3, 11)) +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 3, 15)) +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 3, 11)) +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 3, 33)) +} + +// To be inferred as `string` +function f2() { +>f2 : Symbol(f2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 4, 1)) + + const { a1, b1 = a1 } = { a1: 'hi' }; +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 8, 11)) +>b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 8, 15)) +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 8, 11)) +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 8, 29)) + + const { a2, b2 = a2 + '!' } = { a2: 'hi' }; +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 9, 11)) +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 9, 15)) +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 9, 11)) +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 9, 35)) +} + +// To be inferred as `string | number` +function f3() { +>f3 : Symbol(f3, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 10, 1)) + + const { a1, b1 = a1 } = { a1: 'hi', b1: 1 }; +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 14, 11)) +>b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 14, 15)) +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 14, 11)) +>a1 : Symbol(a1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 14, 29)) +>b1 : Symbol(b1, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 14, 39)) + + const { a2, b2 = a2 + '!' } = { a2: 'hi', b2: 1 }; +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 15, 11)) +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 15, 15)) +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 15, 11)) +>a2 : Symbol(a2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 15, 35)) +>b2 : Symbol(b2, Decl(destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts, 15, 45)) +} + diff --git a/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.types b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.types new file mode 100644 index 0000000000000..ed6c2bf108b29 --- /dev/null +++ b/tests/baselines/reference/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.types @@ -0,0 +1,74 @@ +=== tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts === +// To be inferred as `number` +function f1() { +>f1 : () => void + + const { a1, b1 = a1 } = { a1: 1 }; +>a1 : number +>b1 : number +>a1 : number +>{ a1: 1 } : { a1: number; b1?: number; } +>a1 : number +>1 : 1 + + const { a2, b2 = 1 + a2 } = { a2: 1 }; +>a2 : number +>b2 : number +>1 + a2 : number +>1 : 1 +>a2 : number +>{ a2: 1 } : { a2: number; b2?: number; } +>a2 : number +>1 : 1 +} + +// To be inferred as `string` +function f2() { +>f2 : () => void + + const { a1, b1 = a1 } = { a1: 'hi' }; +>a1 : string +>b1 : string +>a1 : string +>{ a1: 'hi' } : { a1: string; b1?: string; } +>a1 : string +>'hi' : "hi" + + const { a2, b2 = a2 + '!' } = { a2: 'hi' }; +>a2 : string +>b2 : string +>a2 + '!' : string +>a2 : string +>'!' : "!" +>{ a2: 'hi' } : { a2: string; b2?: string; } +>a2 : string +>'hi' : "hi" +} + +// To be inferred as `string | number` +function f3() { +>f3 : () => void + + const { a1, b1 = a1 } = { a1: 'hi', b1: 1 }; +>a1 : string +>b1 : string | number +>a1 : string +>{ a1: 'hi', b1: 1 } : { a1: string; b1?: number; } +>a1 : string +>'hi' : "hi" +>b1 : number +>1 : 1 + + const { a2, b2 = a2 + '!' } = { a2: 'hi', b2: 1 }; +>a2 : string +>b2 : string | number +>a2 + '!' : string +>a2 : string +>'!' : "!" +>{ a2: 'hi', b2: 1 } : { a2: string; b2?: number; } +>a2 : string +>'hi' : "hi" +>b2 : number +>1 : 1 +} + diff --git a/tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts b/tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts new file mode 100644 index 0000000000000..fecc40937fcd3 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment5SiblingInitializer.ts @@ -0,0 +1,19 @@ +// @noImplicitAny: true + +// To be inferred as `number` +function f1() { + const [a1, b1 = a1] = [1]; + const [a2, b2 = 1 + a2] = [1]; +} + +// To be inferred as `string` +function f2() { + const [a1, b1 = a1] = ['hi']; + const [a2, b2 = a2 + '!'] = ['hi']; +} + +// To be inferred as `string | number` +function f3() { + const [a1, b1 = a1] = ['hi', 1]; + const [a2, b2 = a2 + '!'] = ['hi', 1]; +} diff --git a/tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts b/tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts new file mode 100644 index 0000000000000..fe343d2a2288f --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment9SiblingInitializer.ts @@ -0,0 +1,19 @@ +// @noImplicitAny: true + +// To be inferred as `number` +function f1() { + const { a1, b1 = a1 } = { a1: 1 }; + const { a2, b2 = 1 + a2 } = { a2: 1 }; +} + +// To be inferred as `string` +function f2() { + const { a1, b1 = a1 } = { a1: 'hi' }; + const { a2, b2 = a2 + '!' } = { a2: 'hi' }; +} + +// To be inferred as `string | number` +function f3() { + const { a1, b1 = a1 } = { a1: 'hi', b1: 1 }; + const { a2, b2 = a2 + '!' } = { a2: 'hi', b2: 1 }; +}