(declaration, parentType)
| 55850 | return parentType && getBindingElementTypeFromParentType(declaration, parentType); |
| 55851 | } |
| 55852 | function getBindingElementTypeFromParentType(declaration, parentType) { |
| 55853 | // If an any type was inferred for parent, infer that for the binding element |
| 55854 | if (isTypeAny(parentType)) { |
| 55855 | return parentType; |
| 55856 | } |
| 55857 | var pattern = declaration.parent; |
| 55858 | // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation |
| 55859 | if (strictNullChecks && declaration.flags & 16777216 /* NodeFlags.Ambient */ && ts.isParameterDeclaration(declaration)) { |
| 55860 | parentType = getNonNullableType(parentType); |
| 55861 | } |
| 55862 | // Filter `undefined` from the type we check against if the parent has an initializer and that initializer is not possibly `undefined` |
| 55863 | else if (strictNullChecks && pattern.parent.initializer && !(getTypeFacts(getTypeOfInitializer(pattern.parent.initializer)) & 65536 /* TypeFacts.EQUndefined */)) { |
| 55864 | parentType = getTypeWithFacts(parentType, 524288 /* TypeFacts.NEUndefined */); |
| 55865 | } |
| 55866 | var type; |
| 55867 | if (pattern.kind === 201 /* SyntaxKind.ObjectBindingPattern */) { |
| 55868 | if (declaration.dotDotDotToken) { |
| 55869 | parentType = getReducedType(parentType); |
| 55870 | if (parentType.flags & 2 /* TypeFlags.Unknown */ || !isValidSpreadType(parentType)) { |
| 55871 | error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types); |
| 55872 | return errorType; |
| 55873 | } |
| 55874 | var literalMembers = []; |
| 55875 | for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { |
| 55876 | var element = _a[_i]; |
| 55877 | if (!element.dotDotDotToken) { |
| 55878 | literalMembers.push(element.propertyName || element.name); |
| 55879 | } |
| 55880 | } |
| 55881 | type = getRestType(parentType, literalMembers, declaration.symbol); |
| 55882 | } |
| 55883 | else { |
| 55884 | // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) |
| 55885 | var name = declaration.propertyName || declaration.name; |
| 55886 | var indexType = getLiteralTypeFromPropertyName(name); |
| 55887 | var declaredType = getIndexedAccessType(parentType, indexType, 32 /* AccessFlags.ExpressionPosition */, name); |
| 55888 | type = getFlowTypeOfDestructuring(declaration, declaredType); |
| 55889 | } |
| 55890 | } |
| 55891 | else { |
| 55892 | // This elementType will be used if the specific property corresponding to this index is not |
| 55893 | // present (aka the tuple element property). This call also checks that the parentType is in |
| 55894 | // fact an iterable or array (depending on target language). |
| 55895 | var elementType = checkIteratedTypeOrElementType(65 /* IterationUse.Destructuring */ | (declaration.dotDotDotToken ? 0 : 128 /* IterationUse.PossiblyOutOfBounds */), parentType, undefinedType, pattern); |
| 55896 | var index_2 = pattern.elements.indexOf(declaration); |
| 55897 | if (declaration.dotDotDotToken) { |
| 55898 | // If the parent is a tuple type, the rest element has a tuple type of the |
| 55899 | // remaining tuple element types. Otherwise, the rest element has an array type with same |
| 55900 | // element type as the parent type. |
| 55901 | type = everyType(parentType, isTupleType) ? |
| 55902 | mapType(parentType, function (t) { return sliceTupleType(t, index_2); }) : |
| 55903 | createArrayType(elementType); |
| 55904 | } |
| 55905 | else if (isArrayLikeType(parentType)) { |
| 55906 | var indexType = getNumberLiteralType(index_2); |
| 55907 | var accessFlags = 32 /* AccessFlags.ExpressionPosition */ | (hasDefaultValue(declaration) ? 16 /* AccessFlags.NoTupleBoundsCheck */ : 0); |
| 55908 | var declaredType = getIndexedAccessTypeOrUndefined(parentType, indexType, accessFlags, declaration.name) || errorType; |
| 55909 | type = getFlowTypeOfDestructuring(declaration, declaredType); |
no test coverage detected