mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Allow tuples to be widened
This commit is contained in:
parent
649e40b171
commit
dfa108f4ec
@ -5299,7 +5299,7 @@ namespace ts {
|
||||
* Check if a Type was written as a tuple type literal.
|
||||
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
|
||||
*/
|
||||
function isTupleType(type: Type): boolean {
|
||||
function isTupleType(type: Type): type is TupleType {
|
||||
return (type.flags & TypeFlags.Tuple) && !!(<TupleType>type).elementTypes;
|
||||
}
|
||||
|
||||
@ -5341,37 +5341,53 @@ namespace ts {
|
||||
if (isArrayType(type)) {
|
||||
return createArrayType(getWidenedType((<TypeReference>type).typeArguments[0]));
|
||||
}
|
||||
if (isTupleType(type)) {
|
||||
return createTupleType(map(type.elementTypes, getWidenedType));
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function reportWideningErrorsInType(type: Type): boolean {
|
||||
function reportWideningErrorsInType(type: Type, expression: Expression): boolean {
|
||||
let errorReported = false;
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
let errorReported = false;
|
||||
forEach((<UnionType>type).types, t => {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
for (let t of (<UnionType>type).types) {
|
||||
if (reportWideningErrorsInType(t, expression)) {
|
||||
errorReported = true;
|
||||
}
|
||||
});
|
||||
return errorReported;
|
||||
}
|
||||
}
|
||||
if (isArrayType(type)) {
|
||||
return reportWideningErrorsInType((<TypeReference>type).typeArguments[0]);
|
||||
return reportWideningErrorsInType((<TypeReference>type).typeArguments[0], expression);
|
||||
}
|
||||
if (isTupleType(type)) {
|
||||
let { elementTypes } = type;
|
||||
for (let i = 0; i < elementTypes.length; i++) {
|
||||
let t = elementTypes[i];
|
||||
if (t.flags & TypeFlags.ContainsUndefinedOrNull) {
|
||||
if (reportWideningErrorsInType(t, expression)) {
|
||||
errorReported = true;
|
||||
}
|
||||
else if (expression.kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
let element = (<ArrayLiteralExpression>expression).elements[i];
|
||||
error(element, Diagnostics.Array_element_at_index_0_implicitly_has_an_1_type, i, typeToString(getWidenedType(t)));
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.ObjectLiteral) {
|
||||
let errorReported = false;
|
||||
forEach(getPropertiesOfObjectType(type), p => {
|
||||
for (let p of getPropertiesOfObjectType(type)) {
|
||||
let t = getTypeOfSymbol(p);
|
||||
if (t.flags & TypeFlags.ContainsUndefinedOrNull) {
|
||||
if (!reportWideningErrorsInType(t)) {
|
||||
if (!reportWideningErrorsInType(t, expression)) {
|
||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t)));
|
||||
}
|
||||
errorReported = true;
|
||||
}
|
||||
});
|
||||
return errorReported;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return errorReported;
|
||||
}
|
||||
|
||||
function reportImplicitAnyError(declaration: Declaration, type: Type) {
|
||||
@ -5409,7 +5425,7 @@ namespace ts {
|
||||
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
|
||||
if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefinedOrNull) {
|
||||
// Report implicit any error within type if possible, otherwise report error on declaration
|
||||
if (!reportWideningErrorsInType(type)) {
|
||||
if (!reportWideningErrorsInType(type, declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).initializer)) {
|
||||
reportImplicitAnyError(declaration, type);
|
||||
}
|
||||
}
|
||||
@ -6785,6 +6801,7 @@ namespace ts {
|
||||
let hasSpreadElement = false;
|
||||
let elementTypes: Type[] = [];
|
||||
let inDestructuringPattern = isAssignmentTarget(node);
|
||||
let typeFlags: TypeFlags;
|
||||
for (let e of elements) {
|
||||
if (inDestructuringPattern && e.kind === SyntaxKind.SpreadElementExpression) {
|
||||
// Given the following situation:
|
||||
@ -6804,21 +6821,23 @@ namespace ts {
|
||||
(languageVersion >= ScriptTarget.ES6 ? getElementTypeOfIterable(restArrayType, /*errorNode*/ undefined) : undefined);
|
||||
if (restElementType) {
|
||||
elementTypes.push(restElementType);
|
||||
typeFlags |= restElementType.flags;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let type = checkExpression(e, contextualMapper);
|
||||
elementTypes.push(type);
|
||||
typeFlags |= type.flags;
|
||||
}
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElementExpression;
|
||||
}
|
||||
if (!hasSpreadElement) {
|
||||
let contextualType = getContextualType(node);
|
||||
if (contextualType && contextualTypeIsTupleLikeType(contextualType) || inDestructuringPattern) {
|
||||
return createTupleType(elementTypes);
|
||||
return addTypeFlags(createTupleType(elementTypes), typeFlags & TypeFlags.RequiresWidening);
|
||||
}
|
||||
}
|
||||
return createArrayType(getUnionType(elementTypes));
|
||||
return addTypeFlags(createArrayType(getUnionType(elementTypes)), typeFlags & TypeFlags.RequiresWidening);
|
||||
}
|
||||
|
||||
function isNumericName(name: DeclarationName): boolean {
|
||||
@ -6934,8 +6953,7 @@ namespace ts {
|
||||
let stringIndexType = getIndexType(IndexKind.String);
|
||||
let numberIndexType = getIndexType(IndexKind.Number);
|
||||
let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
|
||||
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull);
|
||||
return result;
|
||||
return addTypeFlags(result, TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull));
|
||||
|
||||
function getIndexType(kind: IndexKind) {
|
||||
if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) {
|
||||
@ -6961,6 +6979,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addTypeFlags(type: Type, flags: TypeFlags): Type {
|
||||
type.flags |= flags;
|
||||
return type;
|
||||
}
|
||||
|
||||
function checkJsxSelfClosingElement(node: JsxSelfClosingElement) {
|
||||
checkJsxOpeningLikeElement(node);
|
||||
|
||||
@ -589,6 +589,7 @@ namespace ts {
|
||||
Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
|
||||
Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." },
|
||||
JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: { code: 7026, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists" },
|
||||
Array_element_at_index_0_implicitly_has_an_1_type: { code: 7027, category: DiagnosticCategory.Error, key: "Array element at index {0} implicitly has an '{1}' type." },
|
||||
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
|
||||
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
|
||||
import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." },
|
||||
|
||||
@ -2347,6 +2347,14 @@
|
||||
"category": "Error",
|
||||
"code": 7026
|
||||
},
|
||||
"JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists": {
|
||||
"category": "Error",
|
||||
"code": 7026
|
||||
},
|
||||
"Array element at index {0} implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7027
|
||||
},
|
||||
|
||||
|
||||
"You cannot rename this element.": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user