8000 Error when binding element has no value in initializer and no default · prmdeveloper/TypeScript@d5ff9ee · GitHub
[go: up one dir, main page]

Skip to content

Commit d5ff9ee

Browse files
committed
Error when binding element has no value in initializer and no default
1 parent 055363c commit d5ff9ee

File tree

4 files changed

+35
-14
lines changed

4 files changed

+35
-14
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2434,6 +2434,7 @@ namespace ts {
24342434
let name = e.propertyName || <Identifier>e.name;
24352435
let symbol = <TransientSymbol>createSymbol(flags, name.text);
24362436
symbol.type = getTypeFromBindingElement(e, includePatternInType);
2437+
symbol.bindingElement = e;
24372438
members[symbol.name] = symbol;
24382439
});
24392440
let result = createAnonymousType(undefined, members, emptyArray, emptyArray, undefined, undefined);
@@ -2451,12 +2452,12 @@ namespace ts {
24512452
}
24522453
// If the pattern has at least one element, and no rest element, then it should imply a tuple type.
24532454
let elementTypes = map(elements, e => e.kind === SyntaxKind.OmittedExpression ? anyType : getTypeFromBindingElement(e, includePatternInType));
2454-
let result = createTupleType(elementTypes);
24552455
if (includePatternInType) {
2456-
result = clone(result);
2456+
let result = createNewTupleType(elementTypes);
24572457
result.pattern = pattern;
2458+
return result;
24582459
}
2459-
return result;
2460+
return createTupleType(elementTypes);
24602461
}
24612462

24622463
// Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
@@ -3124,7 +3125,7 @@ namespace ts {
31243125
}
31253126

31263127
function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreReturnTypes: boolean): Signature {
3127-
for (let s of signatureList) {
3128+
for (let s of signatureList) {
31283129
if (compareSignatures(s, signature, partialMatch, ignoreReturnTypes, compareTypes)) {
31293130
return s;
31303131
}
@@ -4045,11 +4046,12 @@ namespace ts {
40454046

40464047
function createTupleType(elementTypes: Type[]) {
40474048
let id = getTypeListId(elementTypes);
4048-
let type = tupleTypes[id];
4049-
if (!type) {
4050-
type = tupleTypes[id] = <TupleType>createObjectType(TypeFlags.Tuple | getPropagatingFlagsOfTypes(elementTypes));
4051-
type.elementTypes = elementTypes;
4052-
}
4049+
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes));
4050+
}
4051+
4052+
function createNewTupleType(elementTypes: Type[]) {
4053+
let type = <TupleType>createObjectType(TypeFlags.Tuple | getPropagatingFlagsOfTypes(elementTypes));
4054+
type.elementTypes = elementTypes;
40534055
return type;
40544056
}
40554057

@@ -7042,19 +7044,28 @@ namespace ts {
70427044
// If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
70437045
// that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
70447046
if (inDestructuringPattern && elementTypes.length) {
7045-
let type = clone(createTupleType(elementTypes));
7047+
let type = createNewTupleType(elementTypes);
70467048
type.pattern = node;
70477049
return type;
70487050
}
70497051
let contextualType = getContextualType(node);
70507052
if (contextualType && contextualTypeIsTupleLikeType(contextualType)) {
70517053
let pattern = contextualType.pattern;
7052-
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the
7053-
// resulting tuple type to make the lengths equal.
7054+
// If array literal is contextually typed by a binding pattern or an assignment pattern, pad the resulting
7055+
// tuple type with the corresponding binding or assignment element types to make the lengths equal.
70547056
if (pattern && (pattern.kind === SyntaxKind.ArrayBindingPattern || pattern.kind === SyntaxKind.ArrayLiteralExpression)) {
70557057
let patternElements = (<BindingPattern | ArrayLiteralExpression>pattern).elements;
70567058
for (let i = elementTypes.length; i < patternElements.length; i++) {
7057-
elementTypes.push(hasDefaultValue(patternElements[i]) ? (<TupleType>contextualType).elementTypes[i] : undefinedType);
7059+
let patternElement = patternElements[i];
7060+
if (hasDefaultValue(patternElement)) {
7061+
elementTypes.push((<TupleType>contextualType).elementTypes[i]);
7062+
}
7063+
else {
7064+
if (patternElement.kind !== SyntaxKind.OmittedExpression) {
7065+
error(patternElement, Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
7066+
}
7067+
elementTypes.push(unknownType);
7068+
}
70587069
}
70597070
}
70607071
if (elementTypes.length) {
@@ -7201,7 +7212,11 @@ namespace ts {
72017212
// type with those properties for which the binding pattern specifies a default value.
72027213
if (contextualTypeHasPattern) {
72037214
for (let prop of getPropertiesOfType(contextualType)) {
7204-
if (prop.flags & SymbolFlags.Optional && !hasProperty(propertiesTable, prop.name)) {
7215+
if (!hasProperty(propertiesTable, prop.name)) {
7216+
if (!(prop.flags & SymbolFlags.Optional)) {
7217+
error(prop.valueDeclaration || (<TransientSymbol>prop).bindingElement,
7218+
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
7219+
}
72057220
propertiesTable[prop.name] = prop;
72067221
propertiesArray.push(prop);
72077222
}

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ namespace ts {
415415
The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_function_expression: { code: 2522, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression." },
416416
yield_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2523, category: DiagnosticCategory.Error, key: "'yield' expressions cannot be used in a parameter initializer." },
417417
await_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2524, category: DiagnosticCategory.Error, key: "'await' expressions cannot be used in a parameter initializer." },
418+
Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: { code: 2525, category: DiagnosticCategory.Error, key: "Initializer provides no value for this binding element and the binding element has no default value" },
418419
JSX_element_attributes_type_0_must_be_an_object_type: { code: 2600, category: DiagnosticCategory.Error, key: "JSX element attributes type '{0}' must be an object type." },
419420
The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: { code: 2601, category: DiagnosticCategory.Error, key: "The return type of a JSX element constructor must return an object type." },
420421
JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: { code: 2602, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist." },

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,10 @@
16491649
"category": "Error",
16501650
"code": 2524
16511651
},
1652+
"Initializer provides no value for this binding element and the binding element has no default value": {
1653+
"category": "Error",
1654+
"code": 2525
1655+
},
16521656
"JSX element attributes type '{0}' must be an object type.": {
16531657
"category": "Error",
16541658
"code": 2600

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,7 @ 5D95 @ namespace ts {
17141714
resolvedExports?: SymbolTable; // Resolved exports of module
17151715
exportsChecked?: boolean; // True if exports of external module have been checked
17161716
isNestedRedeclaration?: boolean; // True if symbol is block scoped redeclaration
1717+
bindingElement?: BindingElement; // Binding element associated with property symbol
17171718
}
17181719

17191720
/* @internal */

0 commit comments

Comments
 (0)
0