docs: function getTypeForBindingElement(declaration) {
              var pattern = declaration.parent;
              var parentType = getTypeForBindingElementParent(pattern.parent);
              // If parent has the unknown (error) type, then so does this binding element
              if (parentType === unknownType) {
                  return unknownType;
              }
              // If no type was specified or inferred for parent, or if the specified or inferred type is any,
              // infer from the initializer of the binding element if one is present. Otherwise, go with the
              // undefined or any type of the parent.
              if (!parentType || isTypeAny(parentType)) {
                  if (declaration.initializer) {
                      return checkExpressionCached(declaration.initializer);
                  }
                  return parentType;
              }
              var type;
              if (pattern.kind === 167 /* ObjectBindingPattern */) {
                  // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                  var name_11 = declaration.propertyName || declaration.name;
                  if (isComputedNonLiteralName(name_11)) {
                      // computed properties with non-literal names are treated as 'any'
                      return anyType;
                  }
                  if (declaration.initializer) {
                      getContextualType(declaration.initializer);
                  }
                  // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
                  // or otherwise the type of the string index signature.
                  var text = getTextOfPropertyName(name_11);
                  type = getTypeOfPropertyOfType(parentType, text) ||
                      isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) ||
                      getIndexTypeOfType(parentType, 0 /* String */);
                  if (!type) {
                      error(name_11, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name_11));
                      return unknownType;
                  }
              }
              else {
                  // This elementType will be used if the specific property corresponding to this index is not
                  // present (aka the tuple element property). This call also checks that the parentType is in
                  // fact an iterable or array (depending on target language).
                  var elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false);
                  if (!declaration.dotDotDotToken) {
                      // Use specific property type when parent is a tuple or numeric index type when parent is an array
                      var propName = "" + ts.indexOf(pattern.elements, declaration);
                      type = isTupleLikeType(parentType)
                          ? getTypeOfPropertyOfType(parentType, propName)
                          : elementType;
                      if (!type) {
                          if (isTupleType(parentType)) {
                              error(declaration, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length);
                          }
                          else {
                              error(declaration, ts.Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName);
                          }
                          return unknownType;
                      }
                  }
                  else {
                      // Rest element has an array type with the same element type as the parent type
                      type = createArrayType(elementType);
                  }
              }
              // In strict null checking mode, if a default value of a non-undefined type is specified, remove
              // undefined from the final type.
              if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkExpressionCached(declaration.initializer)) & 2048 /* Undefined */)) {
                  type = getTypeWithFacts(type, 131072 /* NEUndefined */);
              }
              return declaration.initializer ?
                  getUnionType([type, checkExpressionCached(declaration.initializer)], /*subtypeReduction*/ true) :
                  type;
          }