From 4fc5f6a5ff4f4894cb2868b952e9c7e55685a951 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 31 May 2019 16:40:22 -0700 Subject: [PATCH 1/7] When binding pattern contextually types x || y, x contextually types y --- src/compiler/checker.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5814b2dcfbf42..bf83323741e64 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18435,11 +18435,13 @@ namespace ts { } return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive; case SyntaxKind.BarBarToken: - // When an || expression has a contextual type, the operands are contextually typed by that type. When an || - // expression has no contextual type, the right operand is contextually typed by the type of the left operand, - // except for the special case of Javascript declarations of the form `namespace.prop = namespace.prop || {}` + // When an || expression has a contextual type, the operands are contextually typed by that type, except + // when that type originates in a binding pattern, the right operand is contextually typed by the type of + // the left operand. When an || expression has no contextual type, the right operand is contextually typed + // by the type of the left operand, except for the special case of Javascript declarations of the form + // `namespace.prop = namespace.prop || {}`. const type = getContextualType(binaryExpression, contextFlags); - return !type && node === right && !isDefaultedExpandoInitializer(binaryExpression) ? + return node === right && (type && type.pattern || !type && !isDefaultedExpandoInitializer(binaryExpression)) ? getTypeOfExpression(left) : type; case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.CommaToken: From 5c7823c8b8d463ec0e3274741d357ea972b775b2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 31 May 2019 16:52:11 -0700 Subject: [PATCH 2/7] Accept new baselines --- .../reference/initializedDestructuringAssignmentTypes.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/initializedDestructuringAssignmentTypes.types b/tests/baselines/reference/initializedDestructuringAssignmentTypes.types index bb30a395cffa5..333fc5d92ccd8 100644 --- a/tests/baselines/reference/initializedDestructuringAssignmentTypes.types +++ b/tests/baselines/reference/initializedDestructuringAssignmentTypes.types @@ -9,7 +9,7 @@ const [, a = ''] = ''.match('') || []; >'' : "" >match : (regexp: string | RegExp) => RegExpMatchArray >'' : "" ->[] : [undefined?, ""?] +>[] : undefined[] a.toFixed() >a.toFixed() : any From d0795afb48f06cf5088d6331dbcf2700da0e9734 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 31 May 2019 16:53:46 -0700 Subject: [PATCH 3/7] Add regression tests --- .../compiler/destructuringAssignmentWithDefault.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cases/compiler/destructuringAssignmentWithDefault.ts b/tests/cases/compiler/destructuringAssignmentWithDefault.ts index 45ade402eb846..ba00ea7ceeeda 100644 --- a/tests/cases/compiler/destructuringAssignmentWithDefault.ts +++ b/tests/cases/compiler/destructuringAssignmentWithDefault.ts @@ -2,3 +2,15 @@ const a: { x?: number } = { }; let x = 0; ({x = 1} = a); + +// Repro from #26235 + +function f1(options?: { color?: string, width?: number }) { + let { color, width } = options || {}; + ({ color, width } = options || {}); +} + +function f2(options?: [string?, number?]) { + let [str, num] = options || []; + [str, num] = options || []; +} From 0895fd6bdc723f1e69097499fa2173c0f1091c5e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 31 May 2019 16:53:53 -0700 Subject: [PATCH 4/7] Accept new baselines --- .../destructuringAssignmentWithDefault.js | 23 +++++++++ ...destructuringAssignmentWithDefault.symbols | 34 ++++++++++++++ .../destructuringAssignmentWithDefault.types | 47 +++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault.js b/tests/baselines/reference/destructuringAssignmentWithDefault.js index df4addf026959..4eedee050bd7a 100644 --- a/tests/baselines/reference/destructuringAssignmentWithDefault.js +++ b/tests/baselines/reference/destructuringAssignmentWithDefault.js @@ -2,6 +2,18 @@ const a: { x?: number } = { }; let x = 0; ({x = 1} = a); + +// Repro from #26235 + +function f1(options?: { color?: string, width?: number }) { + let { color, width } = options || {}; + ({ color, width } = options || {}); +} + +function f2(options?: [string?, number?]) { + let [str, num] = options || []; + [str, num] = options || []; +} //// [destructuringAssignmentWithDefault.js] @@ -9,3 +21,14 @@ var _a; var a = {}; var x = 0; (_a = a.x, x = _a === void 0 ? 1 : _a); +// Repro from #26235 +function f1(options) { + var _a; + var _b = options || {}, color = _b.color, width = _b.width; + (_a = options || {}, color = _a.color, width = _a.width); +} +function f2(options) { + var _a; + var _b = options || [], str = _b[0], num = _b[1]; + _a = options || [], str = _a[0], num = _a[1]; +} diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault.symbols b/tests/baselines/reference/destructuringAssignmentWithDefault.symbols index b011834c4f09f..071740ebdde4b 100644 --- a/tests/baselines/reference/destructuringAssignmentWithDefault.symbols +++ b/tests/baselines/reference/destructuringAssignmentWithDefault.symbols @@ -10,3 +10,37 @@ let x = 0; >x : Symbol(x, Decl(destructuringAssignmentWithDefault.ts, 2, 2)) >a : Symbol(a, Decl(destructuringAssignmentWithDefault.ts, 0, 5)) +// Repro from #26235 + +function f1(options?: { color?: string, width?: number }) { +>f1 : Symbol(f1, Decl(destructuringAssignmentWithDefault.ts, 2, 14)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12)) +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23)) +>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 6, 39)) + + let { color, width } = options || {}; +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 7, 9)) +>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 7, 16)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12)) + + ({ color, width } = options || {}); +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 8, 6)) +>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 8, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12)) +} + +function f2(options?: [string?, number?]) { +>f2 : Symbol(f2, Decl(destructuringAssignmentWithDefault.ts, 9, 1)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 11, 12)) + + let [str, num] = options || []; +>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 12, 9)) +>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 12, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 11, 12)) + + [str, num] = options || []; +>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 12, 9)) +>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 12, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 11, 12)) +} + diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault.types b/tests/baselines/reference/destructuringAssignmentWithDefault.types index 6347ccd018877..34f377774b588 100644 --- a/tests/baselines/reference/destructuringAssignmentWithDefault.types +++ b/tests/baselines/reference/destructuringAssignmentWithDefault.types @@ -16,3 +16,50 @@ let x = 0; >1 : 1 >a : { x?: number | undefined; } +// Repro from #26235 + +function f1(options?: { color?: string, width?: number }) { +>f1 : (options?: { color?: string | undefined; width?: number | undefined; } | undefined) => void +>options : { color?: string | undefined; width?: number | undefined; } | undefined +>color : string | undefined +>width : number | undefined + + let { color, width } = options || {}; +>color : string | undefined +>width : number | undefined +>options || {} : { color?: string | undefined; width?: number | undefined; } +>options : { color?: string | undefined; width?: number | undefined; } | undefined +>{} : {} + + ({ color, width } = options || {}); +>({ color, width } = options || {}) : { color?: string | undefined; width?: number | undefined; } +>{ color, width } = options || {} : { color?: string | undefined; width?: number | undefined; } +>{ color, width } : { color: string | undefined; width: number | undefined; } +>color : string | undefined +>width : number | undefined +>options || {} : { color?: string | undefined; width?: number | undefined; } +>options : { color?: string | undefined; width?: number | undefined; } | undefined +>{} : {} +} + +function f2(options?: [string?, number?]) { +>f2 : (options?: [(string | undefined)?, (number | undefined)?] | undefined) => void +>options : [(string | undefined)?, (number | undefined)?] | undefined + + let [str, num] = options || []; +>str : string | undefined +>num : number | undefined +>options || [] : [(string | undefined)?, (number | undefined)?] +>options : [(string | undefined)?, (number | undefined)?] | undefined +>[] : [] + + [str, num] = options || []; +>[str, num] = options || [] : [(string | undefined)?, (number | undefined)?] +>[str, num] : [string | undefined, number | undefined] +>str : string | undefined +>num : number | undefined +>options || [] : [(string | undefined)?, (number | undefined)?] +>options : [(string | undefined)?, (number | undefined)?] | undefined +>[] : [] +} + From d548f6af70fced8f029b4d8fef85713774893099 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 1 Jun 2019 09:45:58 -0700 Subject: [PATCH 5/7] Consider object literals in unions to have properties of type 'undefined' --- src/compiler/checker.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf83323741e64..781f24f5d5ee1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8016,10 +8016,13 @@ namespace ts { else if (isUnion) { const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number) || getIndexInfoOfType(type, IndexKind.String)); if (indexInfo) { - checkFlags |= indexInfo.isReadonly ? CheckFlags.Readonly : 0; - checkFlags |= CheckFlags.WritePartial; + checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0); indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); } + else if (isObjectLiteralType(type)) { + checkFlags |= CheckFlags.WritePartial; + indexTypes = append(indexTypes, undefinedType); + } else { checkFlags |= CheckFlags.ReadPartial; } @@ -20181,7 +20184,8 @@ namespace ts { let propType: Type; const leftType = checkNonNullExpression(left); const parentSymbol = getNodeLinks(left).resolvedSymbol; - const apparentType = getApparentType(getWidenedType(leftType)); + // We widen array literals to get type any[] instead of undefined[] in non-strict mode + const apparentType = getApparentType(isEmptyArrayLiteralType(leftType) ? getWidenedType(leftType) : leftType); if (isTypeAny(apparentType) || apparentType === silentNeverType) { if (isIdentifier(left) && parentSymbol) { markAliasReferenced(parentSymbol, node); From 86040e069932260ede34c400160a44034c262f6b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 1 Jun 2019 10:36:53 -0700 Subject: [PATCH 6/7] Add more tests --- .../destructuringAssignmentWithDefault.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/cases/compiler/destructuringAssignmentWithDefault.ts b/tests/cases/compiler/destructuringAssignmentWithDefault.ts index ba00ea7ceeeda..76b0e71c3732d 100644 --- a/tests/cases/compiler/destructuringAssignmentWithDefault.ts +++ b/tests/cases/compiler/destructuringAssignmentWithDefault.ts @@ -8,9 +8,25 @@ let x = 0; function f1(options?: { color?: string, width?: number }) { let { color, width } = options || {}; ({ color, width } = options || {}); + let x1 = (options || {}).color; + let x2 = (options || {})["color"]; } function f2(options?: [string?, number?]) { let [str, num] = options || []; [str, num] = options || []; + let x1 = (options || {})[0]; +} + +function f3(options?: { color: string, width: number }) { + let { color, width } = options || {}; + ({ color, width } = options || {}); + let x1 = (options || {}).color; + let x2 = (options || {})["color"]; +} + +function f4(options?: [string, number]) { + let [str, num] = options || []; + [str, num] = options || []; + let x1 = (options || {})[0]; } From 48d343b9852acd673c38ad0c43a93aada3935e79 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 1 Jun 2019 10:37:02 -0700 Subject: [PATCH 7/7] Accept new baselines --- .../destructuringAssignmentWithDefault.js | 32 ++++++ ...destructuringAssignmentWithDefault.symbols | 80 +++++++++++++-- .../destructuringAssignmentWithDefault.types | 99 +++++++++++++++++++ 3 files changed, 203 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault.js b/tests/baselines/reference/destructuringAssignmentWithDefault.js index 4eedee050bd7a..b2b0c31654bfc 100644 --- a/tests/baselines/reference/destructuringAssignmentWithDefault.js +++ b/tests/baselines/reference/destructuringAssignmentWithDefault.js @@ -8,11 +8,27 @@ let x = 0; function f1(options?: { color?: string, width?: number }) { let { color, width } = options || {}; ({ color, width } = options || {}); + let x1 = (options || {}).color; + let x2 = (options || {})["color"]; } function f2(options?: [string?, number?]) { let [str, num] = options || []; [str, num] = options || []; + let x1 = (options || {})[0]; +} + +function f3(options?: { color: string, width: number }) { + let { color, width } = options || {}; + ({ color, width } = options || {}); + let x1 = (options || {}).color; + let x2 = (options || {})["color"]; +} + +function f4(options?: [string, number]) { + let [str, num] = options || []; + [str, num] = options || []; + let x1 = (options || {})[0]; } @@ -26,9 +42,25 @@ function f1(options) { var _a; var _b = options || {}, color = _b.color, width = _b.width; (_a = options || {}, color = _a.color, width = _a.width); + var x1 = (options || {}).color; + var x2 = (options || {})["color"]; } function f2(options) { var _a; var _b = options || [], str = _b[0], num = _b[1]; _a = options || [], str = _a[0], num = _a[1]; + var x1 = (options || {})[0]; +} +function f3(options) { + var _a; + var _b = options || {}, color = _b.color, width = _b.width; + (_a = options || {}, color = _a.color, width = _a.width); + var x1 = (options || {}).color; + var x2 = (options || {})["color"]; +} +function f4(options) { + var _a; + var _b = options || [], str = _b[0], num = _b[1]; + _a = options || [], str = _a[0], num = _a[1]; + var x1 = (options || {})[0]; } diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault.symbols b/tests/baselines/reference/destructuringAssignmentWithDefault.symbols index 071740ebdde4b..eef4bdcd97a2a 100644 --- a/tests/baselines/reference/destructuringAssignmentWithDefault.symbols +++ b/tests/baselines/reference/destructuringAssignmentWithDefault.symbols @@ -27,20 +27,84 @@ function f1(options?: { color?: string, width?: number }) { >color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 8, 6)) >width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 8, 13)) >options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12)) + + let x1 = (options || {}).color; +>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 9, 7)) +>(options || {}).color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12)) +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23)) + + let x2 = (options || {})["color"]; +>x2 : Symbol(x2, Decl(destructuringAssignmentWithDefault.ts, 10, 7)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 6, 12)) +>"color" : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 6, 23)) } function f2(options?: [string?, number?]) { ->f2 : Symbol(f2, Decl(destructuringAssignmentWithDefault.ts, 9, 1)) ->options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 11, 12)) +>f2 : Symbol(f2, Decl(destructuringAssignmentWithDefault.ts, 11, 1)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12)) let [str, num] = options || []; ->str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 12, 9)) ->num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 12, 13)) ->options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 11, 12)) +>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 14, 9)) +>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 14, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12)) [str, num] = options || []; ->str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 12, 9)) ->num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 12, 13)) ->options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 11, 12)) +>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 14, 9)) +>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 14, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12)) + + let x1 = (options || {})[0]; +>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 16, 7)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 13, 12)) +>0 : Symbol(0) +} + +function f3(options?: { color: string, width: number }) { +>f3 : Symbol(f3, Decl(destructuringAssignmentWithDefault.ts, 17, 1)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12)) +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23)) +>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 19, 38)) + + let { color, width } = options || {}; +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 20, 9)) +>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 20, 16)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12)) + + ({ color, width } = options || {}); +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 21, 6)) +>width : Symbol(width, Decl(destructuringAssignmentWithDefault.ts, 21, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12)) + + let x1 = (options || {}).color; +>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 22, 7)) +>(options || {}).color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12)) +>color : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23)) + + let x2 = (options || {})["color"]; +>x2 : Symbol(x2, Decl(destructuringAssignmentWithDefault.ts, 23, 7)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 19, 12)) +>"color" : Symbol(color, Decl(destructuringAssignmentWithDefault.ts, 19, 23)) +} + +function f4(options?: [string, number]) { +>f4 : Symbol(f4, Decl(destructuringAssignmentWithDefault.ts, 24, 1)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12)) + + let [str, num] = options || []; +>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 27, 9)) +>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 27, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12)) + + [str, num] = options || []; +>str : Symbol(str, Decl(destructuringAssignmentWithDefault.ts, 27, 9)) +>num : Symbol(num, Decl(destructuringAssignmentWithDefault.ts, 27, 13)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12)) + + let x1 = (options || {})[0]; +>x1 : Symbol(x1, Decl(destructuringAssignmentWithDefault.ts, 29, 7)) +>options : Symbol(options, Decl(destructuringAssignmentWithDefault.ts, 26, 12)) +>0 : Symbol(0) } diff --git a/tests/baselines/reference/destructuringAssignmentWithDefault.types b/tests/baselines/reference/destructuringAssignmentWithDefault.types index 34f377774b588..379bfe8b3bdbd 100644 --- a/tests/baselines/reference/destructuringAssignmentWithDefault.types +++ b/tests/baselines/reference/destructuringAssignmentWithDefault.types @@ -40,6 +40,24 @@ function f1(options?: { color?: string, width?: number }) { >options || {} : { color?: string | undefined; width?: number | undefined; } >options : { color?: string | undefined; width?: number | undefined; } | undefined >{} : {} + + let x1 = (options || {}).color; +>x1 : string | undefined +>(options || {}).color : string | undefined +>(options || {}) : { color?: string | undefined; width?: number | undefined; } +>options || {} : { color?: string | undefined; width?: number | undefined; } +>options : { color?: string | undefined; width?: number | undefined; } | undefined +>{} : {} +>color : string | undefined + + let x2 = (options || {})["color"]; +>x2 : string | undefined +>(options || {})["color"] : string | undefined +>(options || {}) : { color?: string | undefined; width?: number | undefined; } +>options || {} : { color?: string | undefined; width?: number | undefined; } +>options : { color?: string | undefined; width?: number | undefined; } | undefined +>{} : {} +>"color" : "color" } function f2(options?: [string?, number?]) { @@ -61,5 +79,86 @@ function f2(options?: [string?, number?]) { >options || [] : [(string | undefined)?, (number | undefined)?] >options : [(string | undefined)?, (number | undefined)?] | undefined >[] : [] + + let x1 = (options || {})[0]; +>x1 : string | undefined +>(options || {})[0] : string | undefined +>(options || {}) : [(string | undefined)?, (number | undefined)?] | {} +>options || {} : [(string | undefined)?, (number | undefined)?] | {} +>options : [(string | undefined)?, (number | undefined)?] | undefined +>{} : {} +>0 : 0 +} + +function f3(options?: { color: string, width: number }) { +>f3 : (options?: { color: string; width: number; } | undefined) => void +>options : { color: string; width: number; } | undefined +>color : string +>width : number + + let { color, width } = options || {}; +>color : string | undefined +>width : number | undefined +>options || {} : { color: string; width: number; } | {} +>options : { color: string; width: number; } | undefined +>{} : {} + + ({ color, width } = options || {}); +>({ color, width } = options || {}) : { color: string; width: number; } | {} +>{ color, width } = options || {} : { color: string; width: number; } | {} +>{ color, width } : { color: string | undefined; width: number | undefined; } +>color : string | undefined +>width : number | undefined +>options || {} : { color: string; width: number; } | {} +>options : { color: string; width: number; } | undefined +>{} : {} + + let x1 = (options || {}).color; +>x1 : string | undefined +>(options || {}).color : string | undefined +>(options || {}) : { color: string; width: number; } | {} +>options || {} : { color: string; width: number; } | {} +>options : { color: string; width: number; } | undefined +>{} : {} +>color : string | undefined + + let x2 = (options || {})["color"]; +>x2 : string | undefined +>(options || {})["color"] : string | undefined +>(options || {}) : { color: string; width: number; } | {} +>options || {} : { color: string; width: number; } | {} +>options : { color: string; width: number; } | undefined +>{} : {} +>"color" : "color" +} + +function f4(options?: [string, number]) { +>f4 : (options?: [string, number] | undefined) => void +>options : [string, number] | undefined + + let [str, num] = options || []; +>str : string | undefined +>num : number | undefined +>options || [] : [] | [string, number] +>options : [string, number] | undefined +>[] : [] + + [str, num] = options || []; +>[str, num] = options || [] : [] | [string, number] +>[str, num] : [string | undefined, number | undefined] +>str : string | undefined +>num : number | undefined +>options || [] : [] | [string, number] +>options : [string, number] | undefined +>[] : [] + + let x1 = (options || {})[0]; +>x1 : string | undefined +>(options || {})[0] : string | undefined +>(options || {}) : [string, number] | {} +>options || {} : [string, number] | {} +>options : [string, number] | undefined +>{} : {} +>0 : 0 }