diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2134e7f9b2992..0c60fbd29ee0a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4620,26 +4620,26 @@ namespace ts { if (typeArguments.length > 0) { const arity = getTypeReferenceArity(type); const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context); - const hasRestElement = (type.target).hasRestElement; if (tupleConstituentNodes) { if ((type.target as TupleType).labeledElementDeclarations) { for (let i = 0; i < tupleConstituentNodes.length; i++) { - const isOptionalOrRest = i >= (type.target).minLength; - const isRest = isOptionalOrRest && hasRestElement && i === arity - 1; - const isOptional = isOptionalOrRest && !isRest; + const flags = (type.target as TupleType).elementFlags[i]; tupleConstituentNodes[i] = factory.createNamedTupleMember( - isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined, + flags & ElementFlags.Variable ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined, factory.createIdentifier(unescapeLeadingUnderscores(getTupleElementLabel((type.target as TupleType).labeledElementDeclarations![i]))), - isOptional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, - isRest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i] + flags & ElementFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, + flags & ElementFlags.Rest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : + tupleConstituentNodes[i] ); } } else { - for (let i = (type.target).minLength; i < Math.min(arity, tupleConstituentNodes.length); i++) { - tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ? - factory.createRestTypeNode(factory.createArrayTypeNode(tupleConstituentNodes[i])) : - factory.createOptionalTypeNode(tupleConstituentNodes[i]); + for (let i = 0; i < Math.min(arity, tupleConstituentNodes.length); i++) { + const flags = (type.target as TupleType).elementFlags[i]; + tupleConstituentNodes[i] = + flags & ElementFlags.Variable ? factory.createRestTypeNode(flags & ElementFlags.Rest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i]) : + flags & ElementFlags.Optional ? factory.createOptionalTypeNode(tupleConstituentNodes[i]) : + tupleConstituentNodes[i]; } } const tupleTypeNode = setEmitFlags(factory.createTupleTypeNode(tupleConstituentNodes), EmitFlags.SingleLine); @@ -8206,13 +8206,14 @@ namespace ts { function getTypeFromArrayBindingPattern(pattern: BindingPattern, includePatternInType: boolean, reportErrors: boolean): Type { const elements = pattern.elements; const lastElement = lastOrUndefined(elements); - const hasRestElement = !!(lastElement && lastElement.kind === SyntaxKind.BindingElement && lastElement.dotDotDotToken); - if (elements.length === 0 || elements.length === 1 && hasRestElement) { + const restElement = lastElement && lastElement.kind === SyntaxKind.BindingElement && lastElement.dotDotDotToken ? lastElement : undefined; + if (elements.length === 0 || elements.length === 1 && restElement) { return languageVersion >= ScriptTarget.ES2015 ? createIterableType(anyType) : anyArrayType; } const elementTypes = map(elements, e => isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors)); - const minLength = findLastIndex(elements, e => !isOmittedExpression(e) && !hasDefaultValue(e), elements.length - (hasRestElement ? 2 : 1)) + 1; - let result = createTupleType(elementTypes, minLength, hasRestElement); + const minLength = findLastIndex(elements, e => !(e === restElement || isOmittedExpression(e) || hasDefaultValue(e)), elements.length - 1) + 1; + const elementFlags = map(elements, (e, i) => e === restElement ? ElementFlags.Rest : i >= minLength ? ElementFlags.Optional : ElementFlags.Required); + let result = createTupleType(elementTypes, elementFlags); if (includePatternInType) { result = cloneTypeReference(result); result.pattern = pattern; @@ -8903,7 +8904,7 @@ namespace ts { function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { - type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters || emptyArray), (type).readonly)]; + type.resolvedBaseTypes = [getTupleBaseType(type)]; } else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { if (type.symbol.flags & SymbolFlags.Class) { @@ -8920,6 +8921,11 @@ namespace ts { return type.resolvedBaseTypes; } + function getTupleBaseType(type: TupleType) { + const elementTypes = sameMap(type.typeParameters, (t, i) => type.elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t); + return createArrayType(getUnionType(elementTypes || emptyArray), type.readonly); + } + function resolveBaseTypesOfClass(type: InterfaceType) { type.resolvedBaseTypes = resolvingEmptyArray; const baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type)); @@ -9775,17 +9781,16 @@ namespace ts { function expandSignatureParametersWithTupleMembers(restType: TupleTypeReference, restIndex: number) { const elementTypes = getTypeArguments(restType); - const minLength = restType.target.minLength; - const tupleRestIndex = restType.target.hasRestElement ? elementTypes.length - 1 : -1; const associatedNames = restType.target.labeledElementDeclarations; const restParams = map(elementTypes, (t, i) => { // Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name const tupleLabelName = !!associatedNames && getTupleElementLabel(associatedNames[i]); const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i); - const checkFlags = i === tupleRestIndex ? CheckFlags.RestParameter : - i >= minLength ? CheckFlags.OptionalParameter : 0; + const flags = restType.target.elementFlags[i]; + const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter : + flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0; const symbol = createSymbol(SymbolFlags.FunctionScopedVariable, name, checkFlags); - symbol.type = i === tupleRestIndex ? createArrayType(t) : t; + symbol.type = flags & ElementFlags.Rest ? createArrayType(t) : t; return symbol; }); return concatenate(sig.parameters.slice(0, restIndex), restParams); @@ -10514,6 +10519,9 @@ namespace ts { return indexedAccess; } } + if (isGenericTupleType(type.objectType)) { + return getIndexTypeOfType(type.objectType, IndexKind.Number); + } const objectConstraint = getSimplifiedTypeOrConstraint(type.objectType); if (objectConstraint && objectConstraint !== type.objectType) { return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType); @@ -10702,6 +10710,9 @@ namespace ts { return keyofConstraintType; } if (t.flags & TypeFlags.IndexedAccess) { + if (isGenericTupleType((t).objectType)) { + return getIndexTypeOfType((t).objectType, IndexKind.Number); + } const baseObjectType = getBaseConstraint((t).objectType); const baseIndexType = getBaseConstraint((t).indexType); const baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType); @@ -11708,9 +11719,11 @@ namespace ts { } } } - // When an 'infer T' declaration is immediately contained in a rest parameter - // declaration, we infer an 'unknown[]' constraint. - else if (grandParent.kind === SyntaxKind.Parameter && (grandParent).dotDotDotToken) { + // When an 'infer T' declaration is immediately contained in a rest parameter declaration, a rest type + // or a named rest tuple element, we infer an 'unknown[]' constraint. + else if (grandParent.kind === SyntaxKind.Parameter && (grandParent).dotDotDotToken || + grandParent.kind === SyntaxKind.RestType || + grandParent.kind === SyntaxKind.NamedTupleMember && (grandParent).dotDotDotToken) { inferences = append(inferences, createArrayType(unknownType)); } } @@ -11840,10 +11853,7 @@ namespace ts { type.resolvedTypeArguments = type.target.localTypeParameters?.map(() => errorType) || emptyArray; error( type.node || currentNode, - type.target.symbol - ? Diagnostics.Type_arguments_for_0_circularly_reference_themselves - : Diagnostics.Tuple_type_arguments_circularly_reference_themselves - , + type.target.symbol ? Diagnostics.Type_arguments_for_0_circularly_reference_themselves : Diagnostics.Tuple_type_arguments_circularly_reference_themselves, type.target.symbol && symbolToString(type.target.symbol) ); } @@ -12338,24 +12348,34 @@ namespace ts { return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]); } - function isTupleRestElement(node: TypeNode) { - return node.kind === SyntaxKind.RestType || (node.kind === SyntaxKind.NamedTupleMember && !!(node as NamedTupleMember).dotDotDotToken); + function getTupleElementFlags(node: TypeNode) { + switch (node.kind) { + case SyntaxKind.OptionalType: + return ElementFlags.Optional; + case SyntaxKind.RestType: + return getRestTypeElementFlags(node as RestTypeNode); + case SyntaxKind.NamedTupleMember: + return (node as NamedTupleMember).questionToken ? ElementFlags.Optional : + (node as NamedTupleMember).dotDotDotToken ? getRestTypeElementFlags(node as NamedTupleMember) : + ElementFlags.Required; + default: + return ElementFlags.Required; + } } - function isTupleOptionalElement(node: TypeNode) { - return node.kind === SyntaxKind.OptionalType || (node.kind === SyntaxKind.NamedTupleMember && !!(node as NamedTupleMember).questionToken); + function getRestTypeElementFlags(node: RestTypeNode | NamedTupleMember) { + return getArrayElementTypeNode(node.type) ? ElementFlags.Rest : ElementFlags.Variadic; } function getArrayOrTupleTargetType(node: ArrayTypeNode | TupleTypeNode): GenericType { const readonly = isReadonlyTypeOperator(node.parent); - if (node.kind === SyntaxKind.ArrayType || node.elements.length === 1 && isTupleRestElement(node.elements[0])) { + const elementType = getArrayElementTypeNode(node); + if (elementType) { return readonly ? globalReadonlyArrayType : globalArrayType; } - const lastElement = lastOrUndefined(node.elements); - const restElement = lastElement && isTupleRestElement(lastElement) ? lastElement : undefined; - const minLength = findLastIndex(node.elements, n => !isTupleOptionalElement(n) && n !== restElement) + 1; - const missingName = some(node.elements, e => e.kind !== SyntaxKind.NamedTupleMember); - return getTupleTypeOfArity(node.elements.length, minLength, !!restElement, readonly, /*associatedNames*/ missingName ? undefined : node.elements as readonly NamedTupleMember[]); + const elementFlags = map((node as TupleTypeNode).elements, getTupleElementFlags); + const missingName = some((node as TupleTypeNode).elements, e => e.kind !== SyntaxKind.NamedTupleMember); + return getTupleTargetType(elementFlags, readonly, /*associatedNames*/ missingName ? undefined : (node as TupleTypeNode).elements as readonly NamedTupleMember[]); } // Return true if the given type reference node is directly aliased or if it needs to be deferred @@ -12429,13 +12449,13 @@ namespace ts { if (target === emptyGenericType) { links.resolvedType = emptyObjectType; } - else if (isDeferredTypeReferenceNode(node)) { + else if (!(node.kind === SyntaxKind.TupleType && some(node.elements, e => !!(getTupleElementFlags(e) & ElementFlags.Variadic))) && isDeferredTypeReferenceNode(node)) { links.resolvedType = node.kind === SyntaxKind.TupleType && node.elements.length === 0 ? target : createDeferredTypeReference(target, node, /*mapper*/ undefined); } else { const elementTypes = node.kind === SyntaxKind.ArrayType ? [getTypeFromTypeNode(node.elementType)] : map(node.elements, getTypeFromTypeNode); - links.resolvedType = createTypeReference(target, elementTypes); + links.resolvedType = createNormalizedTypeReference(target, elementTypes); } } return links.resolvedType; @@ -12445,6 +12465,28 @@ namespace ts { return isTypeOperatorNode(node) && node.operator === SyntaxKind.ReadonlyKeyword; } + function createTupleType(elementTypes: readonly Type[], elementFlags?: readonly ElementFlags[], readonly = false, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]) { + const tupleTarget = getTupleTargetType(elementFlags || map(elementTypes, _ => ElementFlags.Required), readonly, namedMemberDeclarations); + return tupleTarget === emptyGenericType ? emptyObjectType : + elementTypes.length ? createNormalizedTypeReference(tupleTarget, elementTypes) : + tupleTarget; + } + + function getTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]): GenericType { + if (elementFlags.length === 1 && elementFlags[0] & ElementFlags.Rest) { + // [...X[]] is equivalent to just X[] + return readonly ? globalReadonlyArrayType : globalArrayType; + } + const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + + (readonly ? "R" : "") + + (namedMemberDeclarations && namedMemberDeclarations.length ? "," + map(namedMemberDeclarations, getNodeId).join(",") : ""); + let type = tupleTypes.get(key); + if (!type) { + tupleTypes.set(key, type = createTupleTargetType(elementFlags, readonly, namedMemberDeclarations)); + } + return type; + } + // We represent tuple types as type references to synthesized generic interface types created by // this function. The types are of the form: // @@ -12452,16 +12494,20 @@ namespace ts { // // Note that the generic type created by this function has no symbol associated with it. The same // is true for each of the synthesized type parameters. - function createTupleTypeOfArity(arity: number, minLength: number, hasRestElement: boolean, readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration)[] | undefined): TupleType { + function createTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration)[] | undefined): TupleType { + const arity = elementFlags.length; + const minLength = findLastIndex(elementFlags, f => !!(f & (ElementFlags.Required | ElementFlags.Variadic))) + 1; let typeParameters: TypeParameter[] | undefined; const properties: Symbol[] = []; - const maxLength = hasRestElement ? arity - 1 : arity; + let combinedFlags: ElementFlags = 0; if (arity) { typeParameters = new Array(arity); for (let i = 0; i < arity; i++) { const typeParameter = typeParameters[i] = createTypeParameter(); - if (i < maxLength) { - const property = createSymbol(SymbolFlags.Property | (i >= minLength ? SymbolFlags.Optional : 0), + const flags = elementFlags[i]; + combinedFlags |= flags; + if (!(combinedFlags & ElementFlags.Variable)) { + const property = createSymbol(SymbolFlags.Property | (flags & ElementFlags.Optional ? SymbolFlags.Optional : 0), "" + i as __String, readonly ? CheckFlags.Readonly : 0); property.tupleLabelDeclaration = namedMemberDeclarations?.[i]; property.type = typeParameter; @@ -12469,10 +12515,16 @@ namespace ts { } } } - const literalTypes = []; - for (let i = minLength; i <= maxLength; i++) literalTypes.push(getLiteralType(i)); + const fixedLength = properties.length; const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String); - lengthSymbol.type = hasRestElement ? numberType : getUnionType(literalTypes); + if (combinedFlags & ElementFlags.Variable) { + lengthSymbol.type = numberType; + } + else { + const literalTypes = []; + for (let i = minLength; i <= arity; i++) literalTypes.push(getLiteralType(i)); + lengthSymbol.type = getUnionType(literalTypes); + } properties.push(lengthSymbol); const type = createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference); type.typeParameters = typeParameters; @@ -12490,44 +12542,108 @@ namespace ts { type.declaredConstructSignatures = emptyArray; type.declaredStringIndexInfo = undefined; type.declaredNumberIndexInfo = undefined; + type.elementFlags = elementFlags; type.minLength = minLength; - type.hasRestElement = hasRestElement; + type.fixedLength = fixedLength; + type.hasRestElement = !!(combinedFlags & ElementFlags.Variable); + type.combinedFlags = combinedFlags; type.readonly = readonly; type.labeledElementDeclarations = namedMemberDeclarations; return type; } - function getTupleTypeOfArity(arity: number, minLength: number, hasRestElement: boolean, readonly: boolean, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]): GenericType { - const key = arity + (hasRestElement ? "+" : ",") + minLength + (readonly ? "R" : "") + (namedMemberDeclarations && namedMemberDeclarations.length ? "," + map(namedMemberDeclarations, getNodeId).join(",") : ""); - let type = tupleTypes.get(key); - if (!type) { - tupleTypes.set(key, type = createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, namedMemberDeclarations)); - } - return type; + function createNormalizedTypeReference(target: GenericType, typeArguments: readonly Type[] | undefined) { + return target.objectFlags & ObjectFlags.Tuple && (target).combinedFlags & ElementFlags.Variadic ? + createNormalizedTupleType(target as TupleType, typeArguments!) : + createTypeReference(target, typeArguments); } - function createTupleType(elementTypes: readonly Type[], minLength = elementTypes.length, hasRestElement = false, readonly = false, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]) { - const arity = elementTypes.length; - if (arity === 1 && hasRestElement) { - return createArrayType(elementTypes[0], readonly); + function createNormalizedTupleType(target: TupleType, elementTypes: readonly Type[]): Type { + // Transform [A, ...(X | Y | Z)] into [A, ...X] | [A, ...Y] | [A, ...Z] + const unionIndex = findIndex(elementTypes, (t, i) => !!(target.elementFlags[i] & ElementFlags.Variadic && t.flags & (TypeFlags.Never | TypeFlags.Union))); + if (unionIndex >= 0) { + return mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, replaceElement(elementTypes, unionIndex, t))); } - const tupleType = getTupleTypeOfArity(arity, minLength, arity > 0 && hasRestElement, readonly, namedMemberDeclarations); - return elementTypes.length ? createTypeReference(tupleType, elementTypes) : tupleType; - } + // If there are no variadic elements with non-generic types, just create a type reference with the same target type. + const spreadIndex = findIndex(elementTypes, (t, i) => !!(target.elementFlags[i] & ElementFlags.Variadic) && !(t.flags & TypeFlags.InstantiableNonPrimitive) && !isGenericMappedType(t)); + if (spreadIndex < 0) { + return createTypeReference(target, elementTypes); + } + // We have non-generic variadic elements that need normalization. + const expandedTypes: Type[] = []; + const expandedFlags: ElementFlags[] = []; + let expandedDeclarations: (NamedTupleMember | ParameterDeclaration)[] | undefined = []; + let optionalIndex = -1; + let restTypes: Type[] | undefined; + for (let i = 0; i < elementTypes.length; i++) { + const type = elementTypes[i]; + const flags = target.elementFlags[i]; + if (flags & ElementFlags.Variadic) { + if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) { + // Generic variadic elements stay as they are (except following a rest element). + addElementOrRest(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]); + } + else if (isTupleType(type)) { + // Spread variadic elements with tuple types into the resulting tuple. + forEach(getTypeArguments(type), (t, n) => addElementOrRest(t, type.target.elementFlags[n], type.target.labeledElementDeclarations?.[n])); + } + else { + // Treat everything else as an array type and create a rest element. + addElementOrRest(isArrayLikeType(type) && getIndexTypeOfType(type, IndexKind.Number) || errorType, ElementFlags.Rest, target.labeledElementDeclarations?.[i]); + } + } + else { + // Copy other element kinds with no change. + addElementOrRest(type, flags, target.labeledElementDeclarations?.[i]); + } + } + if (restTypes) { + // Create a union of the collected rest element types. + expandedTypes[expandedTypes.length - 1] = getUnionType(restTypes); + } + const tupleTarget = getTupleTargetType(expandedFlags, target.readonly, expandedDeclarations); + return tupleTarget === emptyGenericType ? emptyObjectType : + expandedFlags.length ? createTypeReference(tupleTarget, expandedTypes) : + tupleTarget; - function sliceTupleType(type: TupleTypeReference, index: number) { - const tuple = type.target; - if (tuple.hasRestElement) { - // don't slice off rest element - index = Math.min(index, getTypeReferenceArity(type) - 1); + function addElementOrRest(type: Type, flags: ElementFlags, declaration: NamedTupleMember | ParameterDeclaration | undefined) { + if (restTypes) { + // A rest element was previously added, so simply collect the type of this element. + restTypes.push(flags & ElementFlags.Variadic ? getIndexedAccessType(type, numberType) : type); + } + else { + if (flags & ElementFlags.Required && optionalIndex >= 0) { + // Turn preceding optional elements into required elements + for (let i = optionalIndex; i < expandedFlags.length; i++) { + if (expandedFlags[i] & ElementFlags.Optional) expandedFlags[i] = ElementFlags.Required; + } + optionalIndex = -1; + } + else if (flags & ElementFlags.Optional && optionalIndex < 0) { + optionalIndex = expandedFlags.length; + } + else if (flags & ElementFlags.Rest) { + // Start collecting element types when a rest element is added. + restTypes = [type]; + } + expandedTypes.push(type); + expandedFlags.push(flags); + if (expandedDeclarations && declaration) { + expandedDeclarations.push(declaration); + } + else { + expandedDeclarations = undefined; + } + } } - return createTupleType( - getTypeArguments(type).slice(index), - Math.max(0, tuple.minLength - index), - tuple.hasRestElement, - tuple.readonly, - tuple.labeledElementDeclarations && tuple.labeledElementDeclarations.slice(index), - ); + } + + function sliceTupleType(type: TupleTypeReference, index: number, endSkipCount = 0) { + const target = type.target; + const endIndex = getTypeReferenceArity(type) - endSkipCount; + return index > target.fixedLength ? getRestArrayTypeOfTupleType(type) || createTupleType(emptyArray) : + createTupleType(getTypeArguments(type).slice(index, endIndex), target.elementFlags.slice(index, endIndex), + /*readonly*/ false, target.labeledElementDeclarations && target.labeledElementDeclarations.slice(index, endIndex)); } function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { @@ -13067,7 +13183,7 @@ namespace ts { type = getReducedType(type); return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : - maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : + type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) ? getIndexTypeForGenericType(type, stringsOnly) : getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String))) : type === wildcardType ? wildcardType : type.flags & TypeFlags.Unknown ? neverType : @@ -13328,7 +13444,7 @@ namespace ts { } return !!((type).objectFlags & ObjectFlags.IsGenericObjectType); } - return !!(type.flags & TypeFlags.InstantiableNonPrimitive) || isGenericMappedType(type); + return !!(type.flags & TypeFlags.InstantiableNonPrimitive) || isGenericMappedType(type) || isGenericTupleType(type); } function isGenericIndexType(type: Type): boolean { @@ -13410,6 +13526,15 @@ namespace ts { // So ultimately (reading): // ((A & B) | C)[K1 | K2] -> ((A & B) | C)[K1] | ((A & B) | C)[K2] -> (A & B)[K1] | C[K1] | (A & B)[K2] | C[K2] -> (A[K1] & B[K1]) | C[K1] | (A[K2] & B[K2]) | C[K2] + // A generic tuple type indexed by a number exists only when the index type doesn't select a + // fixed element. We simplify to either the combined type of all elements (when the index type + // the actual number type) or to the combined type of all non-fixed elements. + if (isGenericTupleType(objectType) && indexType.flags & TypeFlags.NumberLike) { + const elementType = getElementTypeOfSliceOfTupleType(objectType, indexType.flags & TypeFlags.Number ? 0 : objectType.target.fixedLength, /*endSkipCount*/ 0, writing); + if (elementType) { + return type[cache] = elementType; + } + } // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we // construct the type Box. @@ -13461,6 +13586,19 @@ namespace ts { return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, AccessFlags.None, aliasSymbol, aliasTypeArguments) || (accessNode ? errorType : unknownType); } + function indexTypeLessThan(indexType: Type, limit: number) { + return everyType(indexType, t => { + if (t.flags & TypeFlags.StringOrNumberLiteral) { + const propName = getPropertyNameFromType(t); + if (isNumericLiteralName(propName)) { + const index = +propName; + return index >= 0 && index < limit; + } + } + return false; + }); + } + function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, accessFlags = AccessFlags.None, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type | undefined { if (objectType === wildcardType || indexType === wildcardType) { return wildcardType; @@ -13470,12 +13608,15 @@ namespace ts { if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { indexType = stringType; } - // If the index type is generic, or if the object type is generic and doesn't originate in an expression, - // we are performing a higher-order index access where we cannot meaningfully access the properties of the - // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in - // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]' - // has always been resolved eagerly using the constraint type of 'this' at the given location. - if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind !== SyntaxKind.IndexedAccessType) && isGenericObjectType(objectType)) { + // If the index type is generic, or if the object type is generic and doesn't originate in an expression and + // the operation isn't exclusively indexing the fixed (non-variadic) portion of a tuple type, we are performing + // a higher-order index access where we cannot meaningfully access the properties of the object type. Note that + // for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in an expression. This is to + // preserve backwards compatibility. For example, an element access 'this["foo"]' has always been resolved + // eagerly using the constraint type of 'this' at the given location. + if (isGenericIndexType(indexType) || (accessNode && accessNode.kind !== SyntaxKind.IndexedAccessType ? + isGenericTupleType(objectType) && !indexTypeLessThan(indexType, objectType.target.fixedLength) : + isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, objectType.target.fixedLength)))) { if (objectType.flags & TypeFlags.AnyOrUnknown) { return objectType; } @@ -14115,19 +14256,34 @@ namespace ts { return links.resolvedType; } + function getTypeFromRestTypeNode(node: RestTypeNode | NamedTupleMember) { + return getTypeFromTypeNode(getArrayElementTypeNode(node.type) || node.type); + } + + function getArrayElementTypeNode(node: TypeNode): TypeNode | undefined { + switch (node.kind) { + case SyntaxKind.ParenthesizedType: + return getArrayElementTypeNode((node as ParenthesizedTypeNode).type); + case SyntaxKind.TupleType: + if ((node as TupleTypeNode).elements.length === 1) { + node = (node as TupleTypeNode).elements[0]; + if (node.kind === SyntaxKind.RestType || node.kind === SyntaxKind.NamedTupleMember && (node as NamedTupleMember).dotDotDotToken) { + return getArrayElementTypeNode((node as RestTypeNode | NamedTupleMember).type); + } + } + break; + case SyntaxKind.ArrayType: + return (node as ArrayTypeNode).elementType; + } + return undefined; + } + function getTypeFromNamedTupleTypeNode(node: NamedTupleMember): Type { const links = getNodeLinks(node); - if (!links.resolvedType) { - let type = getTypeFromTypeNode(node.type); - if (node.dotDotDotToken) { - type = getElementTypeOfArrayType(type) || errorType; - } - if (node.questionToken && strictNullChecks) { - type = getOptionalType(type); - } - links.resolvedType = type; - } - return links.resolvedType; + return links.resolvedType || (links.resolvedType = + node.dotDotDotToken ? getTypeFromRestTypeNode(node) : + node.questionToken && strictNullChecks ? getOptionalType(getTypeFromTypeNode(node.type)) : + getTypeFromTypeNode(node.type)); } function getTypeFromTypeNode(node: TypeNode): Type { @@ -14197,7 +14353,7 @@ namespace ts { case SyntaxKind.JSDocTypeExpression: return getTypeFromTypeNode((node).type); case SyntaxKind.RestType: - return getElementTypeOfArrayType(getTypeFromTypeNode((node).type)) || errorType; + return getTypeFromRestTypeNode(node); case SyntaxKind.JSDocVariadicType: return getTypeFromJSDocVariadicType(node as JSDocVariadicType); case SyntaxKind.FunctionType: @@ -14523,6 +14679,9 @@ namespace ts { if (typeVariable !== mappedTypeVariable) { return mapType(getReducedType(mappedTypeVariable), t => { if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && t !== errorType) { + if (isGenericTupleType(t)) { + return instantiateMappedGenericTupleType(t, type, typeVariable, mapper); + } const replacementMapper = prependTypeMapping(typeVariable, t, mapper); return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) : isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) : @@ -14539,6 +14698,23 @@ namespace ts { return modifiers & MappedTypeModifiers.IncludeReadonly ? true : modifiers & MappedTypeModifiers.ExcludeReadonly ? false : state; } + function instantiateMappedGenericTupleType(tupleType: TupleTypeReference, mappedType: MappedType, typeVariable: TypeVariable, mapper: TypeMapper) { + // When a tuple type is generic (i.e. when it contains variadic elements), we want to eagerly map the + // non-generic elements and defer mapping the generic elements. In order to facilitate this, we transform + // M<[A, B?, ...T, ...C[]] into [...M<[A]>, ...M<[B?]>, ...M, ...M] and then rely on tuple type + // normalization to resolve the non-generic parts of the resulting tuple. + const elementFlags = tupleType.target.elementFlags; + const elementTypes = map(getTypeArguments(tupleType), (t, i) => { + const singleton = elementFlags[i] & ElementFlags.Variadic ? t : + elementFlags[i] & ElementFlags.Rest ? createArrayType(t) : + createTupleType([t], [elementFlags[i]]); + // The singleton is never a generic tuple type, so it is safe to recurse here. + return instantiateMappedType(mappedType, prependTypeMapping(typeVariable, singleton, mapper)); + }); + const newReadonly = getModifiedReadonlyState(tupleType.target.readonly, getMappedTypeModifiers(mappedType)); + return createTupleType(elementTypes, map(elementTypes, _ => ElementFlags.Variadic), newReadonly); + } + function instantiateMappedArrayType(arrayType: Type, mappedType: MappedType, mapper: TypeMapper) { const elementType = instantiateMappedTypeTemplate(mappedType, numberType, /*isOptional*/ true, mapper); return elementType === errorType ? errorType : @@ -14546,16 +14722,16 @@ namespace ts { } function instantiateMappedTupleType(tupleType: TupleTypeReference, mappedType: MappedType, mapper: TypeMapper) { - const minLength = tupleType.target.minLength; + const elementFlags = tupleType.target.elementFlags; const elementTypes = map(getTypeArguments(tupleType), (_, i) => - instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), i >= minLength, mapper)); + instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), !!(elementFlags[i] & ElementFlags.Optional), mapper)); const modifiers = getMappedTypeModifiers(mappedType); - const newMinLength = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : - modifiers & MappedTypeModifiers.ExcludeOptional ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) : - minLength; + const newTupleModifiers = modifiers & MappedTypeModifiers.IncludeOptional ? map(elementFlags, f => f & ElementFlags.Required ? ElementFlags.Optional : f) : + modifiers & MappedTypeModifiers.ExcludeOptional ? map(elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) : + elementFlags; const newReadonly = getModifiedReadonlyState(tupleType.target.readonly, modifiers); return contains(elementTypes, errorType) ? errorType : - createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, newReadonly, tupleType.target.labeledElementDeclarations); + createTupleType(elementTypes, newTupleModifiers, newReadonly, tupleType.target.labeledElementDeclarations); } function instantiateMappedTypeTemplate(type: MappedType, key: Type, isOptional: boolean, mapper: TypeMapper) { @@ -14661,7 +14837,7 @@ namespace ts { if (objectFlags & ObjectFlags.Reference && !((type).node)) { const resolvedTypeArguments = (type).resolvedTypeArguments; const newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper); - return newTypeArguments !== resolvedTypeArguments ? createTypeReference((type).target, newTypeArguments) : type; + return newTypeArguments !== resolvedTypeArguments ? createNormalizedTypeReference((type).target, newTypeArguments) : type; } return getObjectTypeInstantiation(type, mapper); } @@ -16647,6 +16823,13 @@ namespace ts { } } + // For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable + // to [...T] when T is constrained to a mutable array or tuple type. + if (isSingleElementGenericTupleType(source) && getTypeArguments(source)[0] === target && !source.target.readonly || + isSingleElementGenericTupleType(target) && getTypeArguments(target)[0] === source && (target.target.readonly || isMutableArrayOrTuple(getBaseConstraintOfType(source) || source))) { + return Ternary.True; + } + if (target.flags & TypeFlags.TypeParameter) { // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. if (getObjectFlags(source) & ObjectFlags.Mapped && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source))) { @@ -17252,6 +17435,80 @@ namespace ts { if (relation === identityRelation) { return propertiesIdenticalTo(source, target, excludedProperties); } + let result = Ternary.True; + if (isTupleType(target)) { + if (isArrayType(source) || isTupleType(source)) { + if (!target.target.readonly && (isReadonlyArrayType(source) || isTupleType(source) && source.target.readonly)) { + return Ternary.False; + } + const sourceArity = getTypeReferenceArity(source); + const targetArity = getTypeReferenceArity(target); + const sourceRestFlag = isTupleType(source) ? source.target.combinedFlags & ElementFlags.Rest : ElementFlags.Rest; + const targetRestFlag = target.target.combinedFlags & ElementFlags.Rest; + const sourceMinLength = isTupleType(source) ? source.target.minLength : 0; + const targetMinLength = target.target.minLength; + if (!sourceRestFlag && sourceArity < targetMinLength) { + if (reportErrors) { + reportError(Diagnostics.Source_has_0_element_s_but_target_requires_1, sourceArity, targetMinLength); + } + return Ternary.False; + } + if (!targetRestFlag && targetArity < sourceMinLength) { + if (reportErrors) { + reportError(Diagnostics.Source_has_0_element_s_but_target_allows_only_1, sourceMinLength, targetArity); + } + return Ternary.False; + } + if (!targetRestFlag && sourceRestFlag) { + if (reportErrors) { + if (sourceMinLength < targetMinLength) { + reportError(Diagnostics.Target_requires_0_element_s_but_source_may_have_fewer, targetMinLength); + } + else { + reportError(Diagnostics.Target_allows_only_0_element_s_but_source_may_have_more, targetArity); + } + } + return Ternary.False; + } + const maxArity = Math.max(sourceArity, targetArity); + for (let i = 0; i < maxArity; i++) { + const targetFlags = i < targetArity ? target.target.elementFlags[i] : targetRestFlag; + const sourceFlags = isTupleType(source) && i < sourceArity ? source.target.elementFlags[i] : sourceRestFlag; + if (sourceFlags && targetFlags) { + if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic) || + (sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable))) { + if (reportErrors) { + reportError(Diagnostics.Element_at_index_0_is_variadic_in_one_type_but_not_in_the_other, i); + } + return Ternary.False; + } + if (targetFlags & ElementFlags.Required) { + if (!(sourceFlags & ElementFlags.Required)) { + if (reportErrors) { + reportError(Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, i, typeToString(source), typeToString(target)); + } + return Ternary.False; + } + } + const sourceType = getTypeArguments(source)[Math.min(i, sourceArity - 1)]; + const targetType = getTypeArguments(target)[Math.min(i, targetArity - 1)]; + const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType; + const related = isRelatedTo(sourceType, targetCheckType, reportErrors, /*headMessage*/ undefined, intersectionState); + if (!related) { + if (reportErrors) { + reportIncompatibleError(Diagnostics.Types_of_property_0_are_incompatible, i); + } + return Ternary.False; + } + result &= related; + } + } + return result; + } + if (target.target.combinedFlags & ElementFlags.Variable) { + return Ternary.False; + } + } const requireOptionalProperties = (relation === subtypeRelation || relation === strictSubtypeRelation) && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source); const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false); if (unmatchedProperty) { @@ -17273,35 +17530,6 @@ namespace ts { } } } - let result = Ternary.True; - if (isTupleType(target)) { - const targetRestType = getRestTypeOfTupleType(target); - if (targetRestType) { - if (!isTupleType(source)) { - return Ternary.False; - } - const sourceRestType = getRestTypeOfTupleType(source); - if (sourceRestType && !isRelatedTo(sourceRestType, targetRestType, reportErrors)) { - if (reportErrors) { - reportError(Diagnostics.Rest_signatures_are_incompatible); - } - return Ternary.False; - } - const targetCount = getTypeReferenceArity(target) - 1; - const sourceCount = getTypeReferenceArity(source) - (sourceRestType ? 1 : 0); - const sourceTypeArguments = getTypeArguments(source); - for (let i = targetCount; i < sourceCount; i++) { - const related = isRelatedTo(sourceTypeArguments[i], targetRestType, reportErrors); - if (!related) { - if (reportErrors) { - reportError(Diagnostics.Property_0_is_incompatible_with_rest_element_type, "" + i); - } - return Ternary.False; - } - result &= related; - } - } - } // We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_ // from the target union, across all members const properties = getPropertiesOfType(target); @@ -18056,7 +18284,7 @@ namespace ts { return reduceLeft(types, (s, t) => isTypeSubtypeOf(t, s) ? t : s)!; } - function isArrayType(type: Type): boolean { + function isArrayType(type: Type): type is TypeReference { return !!(getObjectFlags(type) & ObjectFlags.Reference) && ((type).target === globalArrayType || (type).target === globalReadonlyArrayType); } @@ -18069,7 +18297,7 @@ namespace ts { } function getElementTypeOfArrayType(type: Type): Type | undefined { - return isArrayType(type) ? getTypeArguments(type as TypeReference)[0] : undefined; + return isArrayType(type) ? getTypeArguments(type)[0] : undefined; } function isArrayLikeType(type: Type): boolean { @@ -18079,7 +18307,7 @@ namespace ts { } function isEmptyArrayLiteralType(type: Type): boolean { - const elementType = isArrayType(type) ? getTypeArguments(type)[0] : undefined; + const elementType = isArrayType(type) ? getTypeArguments(type)[0] : undefined; return elementType === undefinedWideningType || elementType === implicitNeverType; } @@ -18176,8 +18404,16 @@ namespace ts { return !!(getObjectFlags(type) & ObjectFlags.Reference && (type).target.objectFlags & ObjectFlags.Tuple); } + function isGenericTupleType(type: Type): type is TupleTypeReference { + return isTupleType(type) && !!(type.target.combinedFlags & ElementFlags.Variadic); + } + + function isSingleElementGenericTupleType(type: Type): type is TupleTypeReference { + return isGenericTupleType(type) && type.target.elementFlags.length === 1; + } + function getRestTypeOfTupleType(type: TupleTypeReference) { - return type.target.hasRestElement ? getTypeArguments(type)[type.target.typeParameters!.length - 1] : undefined; + return getElementTypeOfSliceOfTupleType(type, type.target.fixedLength); } function getRestArrayTypeOfTupleType(type: TupleTypeReference) { @@ -18185,8 +18421,27 @@ namespace ts { return restType && createArrayType(restType); } - function getLengthOfTupleType(type: TupleTypeReference) { - return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0); + function getEndLengthOfType(type: Type) { + return isTupleType(type) ? getTypeReferenceArity(type) - findLastIndex(type.target.elementFlags, f => !!(f & ElementFlags.Variable)) - 1 : 0; + } + + function getElementTypeOfSliceOfTupleType(type: TupleTypeReference, index: number, endSkipCount = 0, writing = false) { + const length = getTypeReferenceArity(type) - endSkipCount; + if (index < length) { + const typeArguments = getTypeArguments(type); + const elementTypes: Type[] = []; + for (let i = index; i < length; i++) { + const t = typeArguments[i]; + elementTypes.push(type.target.elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t); + } + return writing ? getIntersectionType(elementTypes) : getUnionType(elementTypes); + } + return undefined; + } + + function isTupleTypeStructureMatching(t1: TupleTypeReference, t2: TupleTypeReference) { + return getTypeReferenceArity(t1) === getTypeReferenceArity(t2) && + every(t1.target.elementFlags, (f, i) => (f & ElementFlags.Variable) === (t2.target.elementFlags[i] & ElementFlags.Variable)); } function isZeroBigInt({value}: BigIntLiteralType) { @@ -18489,7 +18744,7 @@ namespace ts { result = getIntersectionType(sameMap((type).types, getWidenedType)); } else if (isArrayType(type) || isTupleType(type)) { - result = createTypeReference((type).target, sameMap(getTypeArguments(type), getWidenedType)); + result = createTypeReference(type.target, sameMap(getTypeArguments(type), getWidenedType)); } if (result && context === undefined) { type.widened = result; @@ -18526,7 +18781,7 @@ namespace ts { } } if (isArrayType(type) || isTupleType(type)) { - for (const t of getTypeArguments(type)) { + for (const t of getTypeArguments(type)) { if (reportWideningErrorsInType(t)) { errorReported = true; } @@ -18709,7 +18964,8 @@ namespace ts { inferredType: undefined, priority: undefined, topLevel: true, - isFixed: false + isFixed: false, + impliedArity: undefined }; } @@ -18721,7 +18977,8 @@ namespace ts { inferredType: inference.inferredType, priority: inference.priority, topLevel: inference.topLevel, - isFixed: inference.isFixed + isFixed: inference.isFixed, + impliedArity: inference.impliedArity }; } @@ -18831,13 +19088,14 @@ namespace ts { // For arrays and tuples we infer new arrays and tuples where the reverse mapping has been // applied to the element type(s). if (isArrayType(source)) { - return createArrayType(inferReverseMappedType(getTypeArguments(source)[0], target, constraint), isReadonlyArrayType(source)); + return createArrayType(inferReverseMappedType(getTypeArguments(source)[0], target, constraint), isReadonlyArrayType(source)); } if (isTupleType(source)) { const elementTypes = map(getTypeArguments(source), t => inferReverseMappedType(t, target, constraint)); - const minLength = getMappedTypeModifiers(target) & MappedTypeModifiers.IncludeOptional ? - getTypeReferenceArity(source) - (source.target.hasRestElement ? 1 : 0) : source.target.minLength; - return createTupleType(elementTypes, minLength, source.target.hasRestElement, source.target.readonly, source.target.labeledElementDeclarations); + const elementFlags = getMappedTypeModifiers(target) & MappedTypeModifiers.IncludeOptional ? + sameMap(source.target.elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) : + source.target.elementFlags; + return createTupleType(elementTypes, elementFlags, source.target.readonly, source.target.labeledElementDeclarations); } // For all other object types we infer a new object type where the reverse mapping has been // applied to the type of each property. @@ -18891,14 +19149,14 @@ namespace ts { } function tupleTypesDefinitelyUnrelated(source: TupleTypeReference, target: TupleTypeReference) { - return target.target.minLength > source.target.minLength || - !getRestTypeOfTupleType(target) && (!!getRestTypeOfTupleType(source) || getLengthOfTupleType(target) < getLengthOfTupleType(source)); + return !(target.target.combinedFlags & ElementFlags.Variadic) && target.target.minLength > source.target.minLength || + !target.target.hasRestElement && (source.target.hasRestElement || target.target.fixedLength < source.target.fixedLength); } function typesDefinitelyUnrelated(source: Type, target: Type) { // Two tuple types with incompatible arities are definitely unrelated. // Two object types that each have a property that is unmatched in the other are definitely unrelated. - return isTupleType(source) && isTupleType(target) && tupleTypesDefinitelyUnrelated(source, target) || + return isTupleType(source) && isTupleType(target) ? tupleTypesDefinitelyUnrelated(source, target) : !!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true) && !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true); } @@ -19395,22 +19653,61 @@ namespace ts { if (!typesDefinitelyUnrelated(source, target)) { if (isArrayType(source) || isTupleType(source)) { if (isTupleType(target)) { - const sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0; - const targetLength = getLengthOfTupleType(target); - const sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source); - const targetRestType = getRestTypeOfTupleType(target); - const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength; - for (let i = 0; i < fixedLength; i++) { - inferFromTypes(i < sourceLength ? getTypeArguments(source)[i] : sourceRestType!, getTypeArguments(target)[i]); + const sourceArity = getTypeReferenceArity(source); + const targetArity = getTypeReferenceArity(target); + const elementTypes = getTypeArguments(target); + const elementFlags = target.target.elementFlags; + // When source and target are tuple types with the same structure (fixed, variadic, and rest are matched + // to the same kind in each position), simply infer between the element types. + if (isTupleType(source) && isTupleTypeStructureMatching(source, target)) { + for (let i = 0; i < targetArity; i++) { + inferFromTypes(getTypeArguments(source)[i], elementTypes[i]); + } + return; } - if (targetRestType) { - const types = fixedLength < sourceLength ? getTypeArguments(source).slice(fixedLength, sourceLength) : []; - if (sourceRestType) { - types.push(sourceRestType); + const startLength = isTupleType(source) ? Math.min(source.target.fixedLength, target.target.fixedLength) : 0; + const sourceRestType = !isTupleType(source) || sourceArity > 0 && source.target.elementFlags[sourceArity - 1] & ElementFlags.Rest ? + getTypeArguments(source)[sourceArity - 1] : undefined; + const endLength = !(target.target.combinedFlags & ElementFlags.Variable) ? 0 : + sourceRestType ? getEndLengthOfType(target) : + Math.min(getEndLengthOfType(source), getEndLengthOfType(target)); + const sourceEndLength = sourceRestType ? 0 : endLength; + // Infer between starting fixed elements. + for (let i = 0; i < startLength; i++) { + inferFromTypes(getTypeArguments(source)[i], elementTypes[i]); + } + if (sourceRestType && sourceArity - startLength === 1) { + // Single rest element remains in source, infer from that to every element in target + for (let i = startLength; i < targetArity - endLength; i++) { + inferFromTypes(elementFlags[i] & ElementFlags.Variadic ? createArrayType(sourceRestType) : sourceRestType, elementTypes[i]); + } + } + else { + const middleLength = targetArity - startLength - endLength; + if (middleLength === 2 && elementFlags[startLength] & elementFlags[startLength + 1] & ElementFlags.Variadic && isTupleType(source)) { + // Middle of target is [...T, ...U] and source is tuple type + const targetInfo = getInferenceInfoForType(elementTypes[startLength]); + if (targetInfo && targetInfo.impliedArity !== undefined) { + // Infer slices from source based on implied arity of T. + inferFromTypes(sliceTupleType(source, startLength, sourceEndLength + sourceArity - targetInfo.impliedArity), elementTypes[startLength]); + inferFromTypes(sliceTupleType(source, startLength + targetInfo.impliedArity, sourceEndLength), elementTypes[startLength + 1]); + } } - if (types.length) { - inferFromTypes(getUnionType(types), targetRestType); + else if (middleLength === 1 && elementFlags[startLength] & ElementFlags.Variadic) { + // Middle of target is exactly one variadic element. Infer the slice between the fixed parts in the source. + inferFromTypes(isTupleType(source) ? sliceTupleType(source, startLength, sourceEndLength) : createArrayType(sourceRestType!), elementTypes[startLength]); } + else if (middleLength === 1 && elementFlags[startLength] & ElementFlags.Rest) { + // Middle of target is exactly one rest element. If middle of source is not empty, infer union of middle element types. + const restType = isTupleType(source) ? getElementTypeOfSliceOfTupleType(source, startLength, sourceEndLength) : sourceRestType; + if (restType) { + inferFromTypes(restType, elementTypes[startLength]); + } + } + } + // Infer between ending fixed elements + for (let i = 0; i < endLength; i++) { + inferFromTypes(sourceRestType || getTypeArguments(source)[sourceArity - i - 1], elementTypes[targetArity - i - 1]); } return; } @@ -22494,7 +22791,7 @@ namespace ts { const args = getEffectiveCallArguments(iife); const indexOfParameter = func.parameters.indexOf(parameter); if (parameter.dotDotDotToken) { - return getSpreadArgumentType(args, indexOfParameter, args.length, anyType, /*context*/ undefined); + return getSpreadArgumentType(args, indexOfParameter, args.length, anyType, /*context*/ undefined, CheckMode.Normal); } const links = getNodeLinks(iife); const cached = links.resolvedSignature; @@ -23333,6 +23630,10 @@ namespace ts { return checkIteratedTypeOrElementType(IterationUse.Spread, arrayOrIterableType, undefinedType, node.expression); } + function checkSyntheticExpression(node: SyntheticExpression): Type { + return node.isSpread ? getIndexedAccessType(node.type, numberType) : node.type; + } + function hasDefaultValue(node: BindingElement | Expression): boolean { return (node.kind === SyntaxKind.BindingElement && !!(node).initializer) || (node.kind === SyntaxKind.BinaryExpression && (node).operatorToken.kind === SyntaxKind.EqualsToken); @@ -23342,24 +23643,22 @@ namespace ts { const elements = node.elements; const elementCount = elements.length; const elementTypes: Type[] = []; - let hasEndingSpreadElement = false; - let hasNonEndingSpreadElement = false; + const elementFlags: ElementFlags[] = []; const contextualType = getApparentTypeOfContextualType(node); const inDestructuringPattern = isAssignmentTarget(node); const inConstContext = isConstContext(node); for (let i = 0; i < elementCount; i++) { const e = elements[i]; - const spread = e.kind === SyntaxKind.SpreadElement && (e).expression; - const spreadType = spread && checkExpression(spread, checkMode, forceTuple); - if (spreadType && isTupleType(spreadType)) { - elementTypes.push(...getTypeArguments(spreadType)); - if (spreadType.target.hasRestElement) { - if (i === elementCount - 1) hasEndingSpreadElement = true; - else hasNonEndingSpreadElement = true; + if (e.kind === SyntaxKind.SpreadElement) { + if (languageVersion < ScriptTarget.ES2015) { + checkExternalEmitHelpers(e, compilerOptions.downlevelIteration ? ExternalEmitHelpers.SpreadIncludes : ExternalEmitHelpers.SpreadArrays); } - } - else { - if (inDestructuringPattern && spreadType) { + const spreadType = checkExpression((e).expression, checkMode, forceTuple); + if (isArrayLikeType(spreadType)) { + elementTypes.push(spreadType); + elementFlags.push(ElementFlags.Variadic); + } + else if (inDestructuringPattern) { // Given the following situation: // var c: {}; // [...c] = ["", 0]; @@ -23373,45 +23672,35 @@ namespace ts { // getContextualTypeForElementExpression, which will crucially not error // if there is no index type / iterated type. const restElementType = getIndexTypeOfType(spreadType, IndexKind.Number) || - getIteratedTypeOrElementType(IterationUse.Destructuring, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false); - if (restElementType) { - elementTypes.push(restElementType); - } + getIteratedTypeOrElementType(IterationUse.Destructuring, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false) || + unknownType; + elementTypes.push(restElementType); + elementFlags.push(ElementFlags.Rest); } else { - const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length); - const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple); - elementTypes.push(type); + elementTypes.push(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, (e).expression)); + elementFlags.push(ElementFlags.Rest); } - if (spread) { // tuples are done above, so these are only arrays - if (i === elementCount - 1) hasEndingSpreadElement = true; - else hasNonEndingSpreadElement = true; - } - } - } - if (!hasNonEndingSpreadElement) { - const minLength = elementTypes.length - (hasEndingSpreadElement ? 1 : 0); - // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such - // that we get the same behavior for "var [x, y] = []" and "[x, y] = []". - let tupleResult; - if (inDestructuringPattern && minLength > 0) { - const type = cloneTypeReference(createTupleType(elementTypes, minLength, hasEndingSpreadElement)); - type.pattern = node; - return type; - } - else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasEndingSpreadElement, elementTypes.length, inConstContext)) { - return createArrayLiteralType(tupleResult); } - else if (forceTuple) { - return createArrayLiteralType(createTupleType(elementTypes, minLength, hasEndingSpreadElement)); + else { + const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length); + const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple); + elementTypes.push(type); + elementFlags.push(ElementFlags.Required); } } + if (inDestructuringPattern) { + return createTupleType(elementTypes, elementFlags); + } + if (forceTuple || inConstContext || contextualType && forEachType(contextualType, isTupleLikeType)) { + return createArrayLiteralType(createTupleType(elementTypes, elementFlags, /*readonly*/ inConstContext)); + } return createArrayLiteralType(createArrayType(elementTypes.length ? - getUnionType(elementTypes, UnionReduction.Subtype) : + getUnionType(sameMap(elementTypes, (t, i) => elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessTypeOrUndefined(t, numberType) || anyType : t), UnionReduction.Subtype) : strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext)); } - function createArrayLiteralType(type: ObjectType) { + function createArrayLiteralType(type: Type) { if (!(getObjectFlags(type) & ObjectFlags.Reference)) { return type; } @@ -23423,13 +23712,6 @@ namespace ts { return literalType; } - function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length, readonly = false) { - // Infer a tuple type when the contextual type is or contains a tuple-like type - if (readonly || (contextualType && forEachType(contextualType, isTupleLikeType))) { - return createTupleType(elementTypes, elementCount - (hasRestElement ? 1 : 0), hasRestElement, readonly); - } - } - function isNumericName(name: DeclarationName): boolean { switch (name.kind) { case SyntaxKind.ComputedPropertyName: @@ -23887,9 +24169,9 @@ namespace ts { const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName); // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName); - childrenPropSymbol.type = childrenTypes.length === 1 ? - childrenTypes[0] : - (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes))); + childrenPropSymbol.type = childrenTypes.length === 1 ? childrenTypes[0] : + childrenContextualType && forEachType(childrenContextualType, isTupleLikeType) ? createTupleType(childrenTypes) : + createArrayType(getUnionType(childrenTypes)); // Fake up a property declaration for the children childrenPropSymbol.valueDeclaration = factory.createPropertySignature(/*modifiers*/ undefined, unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined); setParent(childrenPropSymbol.valueDeclaration, attributes); @@ -25303,29 +25585,10 @@ namespace ts { // If we are missing the close parenthesis, the call is incomplete. callIsIncomplete = node.arguments.end === node.end; - // If one or more spread arguments are present, check that they correspond to a rest parameter or at least that they are in the valid range. - const firstSpreadArgIndex = getSpreadArgumentIndex(args); - if (firstSpreadArgIndex >= 0) { - if (firstSpreadArgIndex === args.length - 1) { - // Special case, handles the munged arguments that we receive in case of a spread in the end (breaks the arg.expression below) - // (see below for code that starts with "const spreadArgument") - return firstSpreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || firstSpreadArgIndex < getParameterCount(signature)); - } - - let totalCount = firstSpreadArgIndex; // count previous arguments - for (let i = firstSpreadArgIndex; i < args.length; i++) { - const arg = args[i]; - if (!isSpreadArgument(arg)) { - totalCount += 1; - } - else { - const argType = flowLoopCount ? checkExpression((arg).expression) : checkExpressionCached((arg).expression); - totalCount += isTupleType(argType) ? getTypeArguments(argType).length - : isArrayType(argType) ? 0 - : 1; - } - } - return totalCount >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || totalCount <= getParameterCount(signature)); + // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range. + const spreadArgIndex = getSpreadArgumentIndex(args); + if (spreadArgIndex >= 0) { + return spreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || spreadArgIndex < getParameterCount(signature)); } } @@ -25462,6 +25725,12 @@ namespace ts { const restType = getNonArrayRestType(signature); const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; + if (restType && restType.flags & TypeFlags.TypeParameter) { + const info = find(context.inferences, info => info.typeParameter === restType); + if (info) { + info.impliedArity = findIndex(args, isSpreadArgument, argCount) < 0 ? args.length - argCount : undefined; + } + } for (let i = 0; i < argCount; i++) { const arg = args[i]; if (arg.kind !== SyntaxKind.OmittedExpression) { @@ -25472,49 +25741,58 @@ namespace ts { } if (restType) { - const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context); + const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context, checkMode); inferTypes(context.inferences, spreadType, restType); } return getInferredTypes(context); } - function getArrayifiedType(type: Type) { - return type.flags & TypeFlags.Union ? mapType(type, getArrayifiedType) : - type.flags & (TypeFlags.Any | TypeFlags.Instantiable) || isMutableArrayOrTuple(type) ? type : - isTupleType(type) ? createTupleType(getTypeArguments(type), type.target.minLength, type.target.hasRestElement, /*readonly*/ false, type.target.labeledElementDeclarations) : - createArrayType(getIndexedAccessType(type, numberType)); + function getMutableArrayOrTupleType(type: Type) { + return type.flags & TypeFlags.Union ? mapType(type, getMutableArrayOrTupleType) : + type.flags & TypeFlags.Any || isMutableArrayOrTuple(getBaseConstraintOfType(type) || type) ? type : + isTupleType(type) ? createTupleType(getTypeArguments(type), type.target.elementFlags, /*readonly*/ false, type.target.labeledElementDeclarations) : + createTupleType([type], [ElementFlags.Variadic]); } - function getSpreadArgumentType(args: readonly Expression[], index: number, argCount: number, restType: Type, context: InferenceContext | undefined) { + function getSpreadArgumentType(args: readonly Expression[], index: number, argCount: number, restType: Type, context: InferenceContext | undefined, checkMode: CheckMode) { if (index >= argCount - 1) { const arg = args[argCount - 1]; if (isSpreadArgument(arg)) { // We are inferring from a spread expression in the last argument position, i.e. both the parameter // and the argument are ...x forms. - return arg.kind === SyntaxKind.SyntheticExpression ? - createArrayType((arg).type) : - getArrayifiedType(checkExpressionWithContextualType((arg).expression, restType, context, CheckMode.Normal)); + return getMutableArrayOrTupleType(arg.kind === SyntaxKind.SyntheticExpression ? (arg).type : + checkExpressionWithContextualType((arg).expression, restType, context, checkMode)); } } const types = []; - const names: (ParameterDeclaration | NamedTupleMember)[] = []; - let spreadIndex = -1; + const flags = []; + const names = []; for (let i = index; i < argCount; i++) { - const contextualType = getIndexedAccessType(restType, getLiteralType(i - index)); - const argType = checkExpressionWithContextualType(args[i], contextualType, context, CheckMode.Normal); - if (spreadIndex < 0 && isSpreadArgument(args[i])) { - spreadIndex = i - index; + const arg = args[i]; + if (isSpreadArgument(arg)) { + const spreadType = arg.kind === SyntaxKind.SyntheticExpression ? (arg).type : checkExpression((arg).expression); + if (isArrayLikeType(spreadType)) { + types.push(spreadType); + flags.push(ElementFlags.Variadic); + } + else { + types.push(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, arg.kind === SyntaxKind.SpreadElement ? (arg).expression : arg)); + flags.push(ElementFlags.Rest); + } } - if (args[i].kind === SyntaxKind.SyntheticExpression && (args[i] as SyntheticExpression).tupleNameSource) { - names.push((args[i] as SyntheticExpression).tupleNameSource!); + else { + const contextualType = getIndexedAccessType(restType, getLiteralType(i - index)); + const argType = checkExpressionWithContextualType(arg, contextualType, context, checkMode); + const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index); + types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); + flags.push(ElementFlags.Required); + } + if (arg.kind === SyntaxKind.SyntheticExpression && (arg as SyntheticExpression).tupleNameSource) { + names.push((arg as SyntheticExpression).tupleNameSource!); } - const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index); - types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); } - return spreadIndex < 0 ? - createTupleType(types, /*minLength*/ undefined, /*hasRestElement*/ undefined, /*readonly*/ undefined, length(names) === length(types) ? names : undefined) : - createTupleType(append(types.slice(0, spreadIndex), getUnionType(types.slice(spreadIndex))), spreadIndex, /*hasRestElement*/ true, /*readonly*/ undefined); + return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined); } function checkTypeArguments(signature: Signature, typeArgumentNodes: readonly TypeNode[], reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | undefined { @@ -25729,7 +26007,7 @@ namespace ts { } } if (restType) { - const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined); + const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined, checkMode); const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined; if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) { Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors"); @@ -25793,19 +26071,27 @@ namespace ts { return node.attributes.properties.length > 0 || (isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : emptyArray; } const args = node.arguments || emptyArray; - const length = args.length; - if (length && isSpreadArgument(args[length - 1]) && getSpreadArgumentIndex(args) === length - 1) { - // We have a spread argument in the last position and no other spread arguments. If the type - // of the argument is a tuple type, spread the tuple elements into the argument list. We can - // call checkExpressionCached because spread expressions never have a contextual type. - const spreadArgument = args[length - 1]; - const type = flowLoopCount ? checkExpression(spreadArgument.expression) : checkExpressionCached(spreadArgument.expression); - if (isTupleType(type)) { - const typeArguments = getTypeArguments(type); - const restIndex = type.target.hasRestElement ? typeArguments.length - 1 : -1; - const syntheticArgs = map(typeArguments, (t, i) => createSyntheticExpression(spreadArgument, t, /*isSpread*/ i === restIndex, type.target.labeledElementDeclarations?.[i])); - return concatenate(args.slice(0, length - 1), syntheticArgs); + const spreadIndex = getSpreadArgumentIndex(args); + if (spreadIndex >= 0) { + // Create synthetic arguments from spreads of tuple types. + const effectiveArgs = args.slice(0, spreadIndex); + for (let i = spreadIndex; i < args.length; i++) { + const arg = args[i]; + // We can call checkExpressionCached because spread expressions never have a contextual type. + const spreadType = arg.kind === SyntaxKind.SpreadElement && (flowLoopCount ? checkExpression((arg).expression) : checkExpressionCached((arg).expression)); + if (spreadType && isTupleType(spreadType)) { + forEach(getTypeArguments(spreadType), (t, i) => { + const flags = spreadType.target.elementFlags[i]; + const syntheticArg = createSyntheticExpression(arg, flags & ElementFlags.Rest ? createArrayType(t) : t, + !!(flags & ElementFlags.Variable), spreadType.target.labeledElementDeclarations?.[i]); + effectiveArgs.push(syntheticArg); + }); + } + else { + effectiveArgs.push(arg); + } } + return effectiveArgs; } return args; } @@ -27409,7 +27695,7 @@ namespace ts { // otherwise would return the type 'undefined'). const restType = getTypeOfSymbol(signature.parameters[paramCount]); const index = pos - paramCount; - if (!isTupleType(restType) || restType.target.hasRestElement || index < getTypeArguments(restType).length) { + if (!isTupleType(restType) || restType.target.hasRestElement || index < restType.target.fixedLength) { return getIndexedAccessType(restType, getLiteralType(index)); } } @@ -27417,37 +27703,30 @@ namespace ts { } function getRestTypeAtPosition(source: Signature, pos: number): Type { - const paramCount = getParameterCount(source); + const parameterCount = getParameterCount(source); + const minArgumentCount = getMinArgumentCount(source); const restType = getEffectiveRestType(source); - const nonRestCount = paramCount - (restType ? 1 : 0); - if (restType && pos === nonRestCount) { - return restType; + if (restType && pos >= parameterCount - 1) { + return pos === parameterCount - 1 ? restType : createArrayType(getIndexedAccessType(restType, numberType)); } const types = []; - let names: (NamedTupleMember | ParameterDeclaration)[] | undefined = []; - for (let i = pos; i < nonRestCount; i++) { - types.push(getTypeAtPosition(source, i)); - const name = getNameableDeclarationAtPosition(source, i); - if (name && names) { - names.push(name); + const flags = []; + const names = []; + for (let i = pos; i < parameterCount; i++) { + if (!restType || i < parameterCount - 1) { + types.push(getTypeAtPosition(source, i)); + flags.push(i < minArgumentCount ? ElementFlags.Required : ElementFlags.Optional); } else { - names = undefined; + types.push(restType); + flags.push(ElementFlags.Variadic); } - } - if (restType) { - types.push(getIndexedAccessType(restType, numberType)); - const name = getNameableDeclarationAtPosition(source, nonRestCount); - if (name && names) { + const name = getNameableDeclarationAtPosition(source, i); + if (name) { names.push(name); } - else { - names = undefined; - } } - const minArgumentCount = getMinArgumentCount(source); - const minLength = minArgumentCount < pos ? 0 : minArgumentCount - pos; - return createTupleType(types, minLength, !!restType, /*readonly*/ false, names); + return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined); } function getParameterCount(signature: Signature) { @@ -27455,7 +27734,7 @@ namespace ts { if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[length - 1]); if (isTupleType(restType)) { - return length + getTypeArguments(restType).length - 1; + return length + restType.target.fixedLength - (restType.target.hasRestElement ? 0 : 1); } } return length; @@ -27465,9 +27744,10 @@ namespace ts { if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); if (isTupleType(restType)) { - const minLength = restType.target.minLength; - if (minLength > 0) { - return signature.parameters.length - 1 + minLength; + const firstOptionalIndex = findIndex(restType.target.elementFlags, f => !(f & ElementFlags.Required)); + const requiredCount = firstOptionalIndex < 0 ? restType.target.fixedLength : firstOptionalIndex; + if (requiredCount > 0) { + return signature.parameters.length - 1 + requiredCount; } } } @@ -27488,7 +27768,12 @@ namespace ts { function getEffectiveRestType(signature: Signature) { if (signatureHasRestParameter(signature)) { const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); - return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType; + if (!isTupleType(restType)) { + return restType; + } + if (restType.target.hasRestElement) { + return sliceTupleType(restType, restType.target.fixedLength); + } } return undefined; } @@ -29380,18 +29665,19 @@ namespace ts { function padTupleType(type: TupleTypeReference, pattern: ArrayBindingPattern) { const patternElements = pattern.elements; - const arity = getTypeReferenceArity(type); - const elementTypes = arity ? getTypeArguments(type).slice() : []; - for (let i = arity; i < patternElements.length; i++) { + const elementTypes = getTypeArguments(type).slice(); + const elementFlags = type.target.elementFlags.slice(); + for (let i = getTypeReferenceArity(type); i < patternElements.length; i++) { const e = patternElements[i]; if (i < patternElements.length - 1 || !(e.kind === SyntaxKind.BindingElement && e.dotDotDotToken)) { elementTypes.push(!isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType); + elementFlags.push(ElementFlags.Optional); if (!isOmittedExpression(e) && !hasDefaultValue(e)) { reportImplicitAny(e, anyType); } } } - return createTupleType(elementTypes, type.target.minLength, /*hasRestElement*/ false, type.target.readonly); + return createTupleType(elementTypes, elementFlags, type.target.readonly); } function widenTypeInferredFromInitializer(declaration: HasExpressionInitializer, type: Type) { @@ -29838,7 +30124,7 @@ namespace ts { case SyntaxKind.YieldExpression: return checkYieldExpression(node); case SyntaxKind.SyntheticExpression: - return (node).type; + return checkSyntheticExpression(node); case SyntaxKind.JsxExpression: return checkJsxExpression(node, checkMode); case SyntaxKind.JsxElement: @@ -30563,16 +30849,20 @@ namespace ts { grammarErrorOnNode(e, Diagnostics.Tuple_members_must_all_have_names_or_all_not_have_names); break; } - if (isTupleRestElement(e)) { + const flags = getTupleElementFlags(e); + if (flags & ElementFlags.Variadic) { + if (!isArrayLikeType(getTypeFromTypeNode((e).type))) { + error(e, Diagnostics.A_rest_element_type_must_be_an_array_type); + break; + } + } + else if (flags & ElementFlags.Rest) { if (i !== elementTypes.length - 1) { grammarErrorOnNode(e, Diagnostics.A_rest_element_must_be_last_in_a_tuple_type); break; } - if (!isArrayType(getTypeFromTypeNode((e).type))) { - error(e, Diagnostics.A_rest_element_type_must_be_an_array_type); - } } - else if (isTupleOptionalElement(e)) { + else if (flags & ElementFlags.Optional) { seenOptionalElement = true; } else if (seenOptionalElement) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4be5998d6f3f9..f93756318c835 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1201,6 +1201,14 @@ namespace ts { return values; } + export function arrayOf(count: number, f: (index: number) => T): T[] { + const result = new Array(count); + for (let i = 0; i < count; i++) { + result[i] = f(i); + } + return result; + } + /** Shims `Array.from`. */ export function arrayFrom(iterator: Iterator | IterableIterator, map: (t: T) => U): U[]; export function arrayFrom(iterator: Iterator | IterableIterator): T[]; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 35d35f7234f9c..9d5bbd0455339 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2414,6 +2414,26 @@ "category": "Error", "code": 2617 }, + "Source has {0} element(s) but target requires {1}.": { + "category": "Error", + "code": 2618 + }, + "Source has {0} element(s) but target allows only {1}.": { + "category": "Error", + "code": 2619 + }, + "Target requires {0} element(s) but source may have fewer.": { + "category": "Error", + "code": 2620 + }, + "Target allows only {0} element(s) but source may have more.": { + "category": "Error", + "code": 2621 + }, + "Element at index {0} is variadic in one type but not in the other.": { + "category": "Error", + "code": 2622 + }, "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { "category": "Error", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d6c06ebec5ff0..12b6262084854 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5099,9 +5099,20 @@ namespace ts { variances?: VarianceFlags[]; // Variance of each type parameter } + export const enum ElementFlags { + Required = 1 << 0, // T + Optional = 1 << 1, // T? + Rest = 1 << 2, // ...T[] + Variadic = 1 << 3, // ...T + Variable = Rest | Variadic, + } + export interface TupleType extends GenericType { + elementFlags: readonly ElementFlags[]; minLength: number; + fixedLength: number; hasRestElement: boolean; + combinedFlags: ElementFlags; readonly: boolean; labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; } @@ -5421,6 +5432,7 @@ namespace ts { priority?: InferencePriority; // Priority of current inference set topLevel: boolean; // True if all inferences are to top level occurrences isFixed: boolean; // True if inferences are fixed + impliedArity?: number; } /* @internal */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 30b789890b3e7..a4a05c8183d37 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2538,9 +2538,19 @@ declare namespace ts { } export interface GenericType extends InterfaceType, TypeReference { } + export enum ElementFlags { + Required = 1, + Optional = 2, + Rest = 4, + Variadic = 8, + Variable = 12 + } export interface TupleType extends GenericType { + elementFlags: readonly ElementFlags[]; minLength: number; + fixedLength: number; hasRestElement: boolean; + combinedFlags: ElementFlags; readonly: boolean; labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c3149e9b7d17e..8cccfe47f2836 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2538,9 +2538,19 @@ declare namespace ts { } export interface GenericType extends InterfaceType, TypeReference { } + export enum ElementFlags { + Required = 1, + Optional = 2, + Rest = 4, + Variadic = 8, + Variable = 12 + } export interface TupleType extends GenericType { + elementFlags: readonly ElementFlags[]; minLength: number; + fixedLength: number; hasRestElement: boolean; + combinedFlags: ElementFlags; readonly: boolean; labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; } diff --git a/tests/baselines/reference/argumentExpressionContextualTyping.errors.txt b/tests/baselines/reference/argumentExpressionContextualTyping.errors.txt index c983abfa1bec8..8dc476ee78918 100644 --- a/tests/baselines/reference/argumentExpressionContextualTyping.errors.txt +++ b/tests/baselines/reference/argumentExpressionContextualTyping.errors.txt @@ -1,11 +1,11 @@ tests/cases/conformance/expressions/contextualTyping/argumentExpressionContextualTyping.ts(16,5): error TS2345: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type '[string, number, boolean]'. - Type '(string | number | boolean)[]' is missing the following properties from type '[string, number, boolean]': 0, 1, 2 + Target requires 3 element(s) but source may have fewer. tests/cases/conformance/expressions/contextualTyping/argumentExpressionContextualTyping.ts(17,5): error TS2345: Argument of type '[string, number, true, ...(string | number | boolean)[]]' is not assignable to parameter of type '[string, number, boolean]'. - Types of property 'length' are incompatible. - Type 'number' is not assignable to type '3'. + Target allows only 3 element(s) but source may have more. tests/cases/conformance/expressions/contextualTyping/argumentExpressionContextualTyping.ts(18,5): error TS2345: Argument of type '{ x: (string | number)[]; y: { c: boolean; d: string; e: number; }; }' is not assignable to parameter of type '{ x: [any, any]; y: { c: any; d: any; e: any; }; }'. Types of property 'x' are incompatible. - Type '(string | number)[]' is missing the following properties from type '[any, any]': 0, 1 + Type '(string | number)[]' is not assignable to type '[any, any]'. + Target requires 2 element(s) but source may have fewer. ==== tests/cases/conformance/expressions/contextualTyping/argumentExpressionContextualTyping.ts (3 errors) ==== @@ -27,14 +27,14 @@ tests/cases/conformance/expressions/contextualTyping/argumentExpressionContextua baz(array); // Error ~~~~~ !!! error TS2345: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type '[string, number, boolean]'. -!!! error TS2345: Type '(string | number | boolean)[]' is missing the following properties from type '[string, number, boolean]': 0, 1, 2 +!!! error TS2345: Target requires 3 element(s) but source may have fewer. baz(["string", 1, true, ...array]); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[string, number, true, ...(string | number | boolean)[]]' is not assignable to parameter of type '[string, number, boolean]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type '3'. +!!! error TS2345: Target allows only 3 element(s) but source may have more. foo(o); // Error because x has an array type namely (string|number)[] ~ !!! error TS2345: Argument of type '{ x: (string | number)[]; y: { c: boolean; d: string; e: number; }; }' is not assignable to parameter of type '{ x: [any, any]; y: { c: any; d: any; e: any; }; }'. !!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type '(string | number)[]' is missing the following properties from type '[any, any]': 0, 1 \ No newline at end of file +!!! error TS2345: Type '(string | number)[]' is not assignable to type '[any, any]'. +!!! error TS2345: Target requires 2 element(s) but source may have fewer. \ No newline at end of file diff --git a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt index 31caaef42283b..a19e0e1b438aa 100644 --- a/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt +++ b/tests/baselines/reference/arityAndOrderCompatibility01.errors.txt @@ -1,21 +1,21 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(15,12): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(17,5): error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2741: Property '2' is missing in type '[string, number]' but required in type '[number, number, number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2741: Property '2' is missing in type 'StrNum' but required in type '[number, number, number]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'. -tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(21,5): error TS2741: Property '2' is missing in type '[string, number]' but required in type '[string, number, number]'. +tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(21,5): error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(22,5): error TS2741: Property '2' is missing in type 'StrNum' but required in type '[string, number, number]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(23,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string, number, number]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'. - Types of property '0' are incompatible. - Type 'string' is not assignable to type 'number'. + Source has 2 element(s) but target allows only 1. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'. Types of property '0' are incompatible. Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'. - Types of property 'length' are incompatible. - Type '2' is not assignable to type '1'. + Source has 2 element(s) but target allows only 1. tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'. Types of property 'length' are incompatible. Type '2' is not assignable to type '1'. @@ -52,7 +52,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error !!! error TS2461: Type '{ 0: string; 1: number; length: 2; }' is not an array type. var j1: [number, number, number] = x; ~~ -!!! error TS2741: Property '2' is missing in type '[string, number]' but required in type '[number, number, number]'. +!!! error TS2322: Type '[string, number]' is not assignable to type '[number, number, number]'. +!!! error TS2322: Source has 2 element(s) but target requires 3. var j2: [number, number, number] = y; ~~ !!! error TS2741: Property '2' is missing in type 'StrNum' but required in type '[number, number, number]'. @@ -61,7 +62,8 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error !!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'. var k1: [string, number, number] = x; ~~ -!!! error TS2741: Property '2' is missing in type '[string, number]' but required in type '[string, number, number]'. +!!! error TS2322: Type '[string, number]' is not assignable to type '[string, number, number]'. +!!! error TS2322: Source has 2 element(s) but target requires 3. var k2: [string, number, number] = y; ~~ !!! error TS2741: Property '2' is missing in type 'StrNum' but required in type '[string, number, number]'. @@ -71,8 +73,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error var l1: [number] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[number]'. -!!! error TS2322: Types of property '0' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Source has 2 element(s) but target allows only 1. var l2: [number] = y; ~~ !!! error TS2322: Type 'StrNum' is not assignable to type '[number]'. @@ -84,8 +85,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error var m1: [string] = x; ~~ !!! error TS2322: Type '[string, number]' is not assignable to type '[string]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '2' is not assignable to type '1'. +!!! error TS2322: Source has 2 element(s) but target allows only 1. var m2: [string] = y; ~~ !!! error TS2322: Type 'StrNum' is not assignable to type '[string]'. diff --git a/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt b/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt index 8c62ba2d6b783..b472e2297a6b1 100644 --- a/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt +++ b/tests/baselines/reference/arrayLiteralExpressionContextualTyping.errors.txt @@ -1,15 +1,11 @@ tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(6,5): error TS2322: Type '[number, number, number, number]' is not assignable to type '[number, number, number]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(7,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[string | number, string | number, string | number]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(8,5): error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts(14,5): error TS2322: Type '[number, number, number, number, number, number]' is not assignable to type '[number, number, number]'. - Types of property 'length' are incompatible. - Type '6' is not assignable to type '3'. + Source has 6 element(s) but target allows only 3. ==== tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionContextualTyping.ts (4 errors) ==== @@ -21,18 +17,15 @@ tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionConte var tup: [number, number, number] = [1, 2, 3, 4]; ~~~ !!! error TS2322: Type '[number, number, number, number]' is not assignable to type '[number, number, number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '4' is not assignable to type '3'. +!!! error TS2322: Source has 4 element(s) but target allows only 3. var tup1: [number|string, number|string, number|string] = [1, 2, 3, "string"]; ~~~~ !!! error TS2322: Type '[number, number, number, string]' is not assignable to type '[string | number, string | number, string | number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '4' is not assignable to type '3'. +!!! error TS2322: Source has 4 element(s) but target allows only 3. var tup2: [number, number, number] = [1, 2, 3, "string"]; // Error ~~~~ !!! error TS2322: Type '[number, number, number, string]' is not assignable to type '[number, number, number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '4' is not assignable to type '3'. +!!! error TS2322: Source has 4 element(s) but target allows only 3. // In a contextually typed array literal expression containing one or more spread elements, // an element expression at index N is contextually typed by the numeric index type of the contextual type, if any. @@ -41,6 +34,5 @@ tests/cases/conformance/expressions/contextualTyping/arrayLiteralExpressionConte var spr2:[number, number, number] = [1, 2, 3, ...tup]; // Error ~~~~ !!! error TS2322: Type '[number, number, number, number, number, number]' is not assignable to type '[number, number, number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '6' is not assignable to type '3'. +!!! error TS2322: Source has 6 element(s) but target allows only 3. \ No newline at end of file diff --git a/tests/baselines/reference/arrayLiterals3.errors.txt b/tests/baselines/reference/arrayLiterals3.errors.txt index 17c3d582b4d6a..8ea3d1583b6fb 100644 --- a/tests/baselines/reference/arrayLiterals3.errors.txt +++ b/tests/baselines/reference/arrayLiterals3.errors.txt @@ -1,11 +1,12 @@ -tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error TS2739: Type '[]' is missing the following properties from type '[any, any, any]': 0, 1, 2 +tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(10,5): error TS2322: Type '[]' is not assignable to type '[any, any, any]'. + Source has 0 element(s) but target requires 3. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,38): error TS2322: Type 'string' is not assignable to type 'boolean'. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,48): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(11,51): error TS2322: Type 'boolean' is not assignable to type 'number'. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '2'. -tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2739: Type 'number[]' is missing the following properties from type '[number, number, number]': 0, 1, 2 + Source has 4 element(s) but target allows only 2. +tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'. + Target requires 3 element(s) but source may have fewer. tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'. The types returned by 'pop()' are incompatible between these types. Type 'string | number' is not assignable to type 'Number'. @@ -24,7 +25,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error var a0: [any, any, any] = []; // Error ~~ -!!! error TS2739: Type '[]' is missing the following properties from type '[any, any, any]': 0, 1, 2 +!!! error TS2322: Type '[]' is not assignable to type '[any, any, any]'. +!!! error TS2322: Source has 0 element(s) but target requires 3. var a1: [boolean, string, number] = ["string", 1, true]; // Error ~~~~~~~~ !!! error TS2322: Type 'string' is not assignable to type 'boolean'. @@ -40,8 +42,7 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error var [b1, b2]: [number, number] = [1, 2, "string", true]; ~~~~~~~~ !!! error TS2322: Type '[number, number, string, boolean]' is not assignable to type '[number, number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '4' is not assignable to type '2'. +!!! error TS2322: Source has 4 element(s) but target allows only 2. // The resulting type an array literal expression is determined as follows: // - the resulting type is an array type with an element type that is the union of the types of the @@ -59,7 +60,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error var c0: tup = [...temp2]; // Error var c1: [number, number, number] = [...temp1]; // Error cannot assign number[] to [number, number, number] ~~ -!!! error TS2739: Type 'number[]' is missing the following properties from type '[number, number, number]': 0, 1, 2 +!!! error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'. +!!! error TS2322: Target requires 3 element(s) but source may have fewer. var c2: myArray = [...temp1, ...temp]; // Error cannot assign (number|string)[] to number[] ~~ !!! error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'. diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt index 0d6aea98dafa1..3fc5d847becc8 100644 --- a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt @@ -1,7 +1,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2741: Property '0' is missing in type '{}[]' but required in type '[{}]'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]'. + Target requires 1 element(s) but source may have fewer. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts (2 errors) ==== @@ -28,5 +29,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'string' is not assignable to type 'number'. emptyObjTuple = emptyObjArray; ~~~~~~~~~~~~~ -!!! error TS2741: Property '0' is missing in type '{}[]' but required in type '[{}]'. +!!! error TS2322: Type '{}[]' is not assignable to type '[{}]'. +!!! error TS2322: Target requires 1 element(s) but source may have fewer. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentLHSIsValue.types b/tests/baselines/reference/assignmentLHSIsValue.types index 81fd5dc537b5a..82dd7f026ad45 100644 --- a/tests/baselines/reference/assignmentLHSIsValue.types +++ b/tests/baselines/reference/assignmentLHSIsValue.types @@ -225,8 +225,8 @@ foo() = value; ([]) = value; >([]) = value : any ->([]) : undefined[] ->[] : undefined[] +>([]) : [] +>[] : [] >value : any (function baz() { }) = value; diff --git a/tests/baselines/reference/assignmentRestElementWithErrorSourceType.types b/tests/baselines/reference/assignmentRestElementWithErrorSourceType.types index 41bdd948d9581..7ef47f6762f55 100644 --- a/tests/baselines/reference/assignmentRestElementWithErrorSourceType.types +++ b/tests/baselines/reference/assignmentRestElementWithErrorSourceType.types @@ -4,7 +4,7 @@ var tuple: [string, number]; [...c] = tupel; // intentionally misspelled >[...c] = tupel : any ->[...c] : undefined[] +>[...c] : any[] >...c : any >c : any >tupel : any diff --git a/tests/baselines/reference/callWithSpread3.errors.txt b/tests/baselines/reference/callWithSpread3.errors.txt index 71fc0334633f8..062c273a26a9c 100644 --- a/tests/baselines/reference/callWithSpread3.errors.txt +++ b/tests/baselines/reference/callWithSpread3.errors.txt @@ -1,17 +1,18 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(14,10): error TS2554: Expected 2 arguments, but got 3. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(15,15): error TS2554: Expected 2 arguments, but got 5. -tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(16,15): error TS2556: Expected 2 arguments, but got 4 or more. -tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(17,15): error TS2556: Expected 2 arguments, but got 5 or more. -tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(18,12): error TS2556: Expected 2 arguments, but got 1 or more. +tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(16,15): error TS2554: Expected 2 arguments, but got 5. +tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(17,15): error TS2554: Expected 2 arguments, but got 6. +tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(18,12): error TS2554: Expected 2 arguments, but got 3. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(19,5): error TS2554: Expected 2 arguments, but got 3. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(20,6): error TS2557: Expected at least 2 arguments, but got 0 or more. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(21,6): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(22,13): error TS2557: Expected at least 2 arguments, but got 1 or more. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(23,13): error TS2557: Expected at least 2 arguments, but got 2 or more. tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(25,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(31,13): error TS2557: Expected at least 2 arguments, but got 4 or more. -==== tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts (11 errors) ==== +==== tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts (12 errors) ==== declare const s2: [string, string]; declare const s3: [string, string, string]; declare const s2_: [string, string, ...string[]]; @@ -33,14 +34,13 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(25,7): erro !!! error TS2554: Expected 2 arguments, but got 5. fs2('a', 'b', ...s2, 'c'); // error on ...s2 and 'c' ~~~~~~~~~~ -!!! error TS2556: Expected 2 arguments, but got 4 or more. +!!! error TS2554: Expected 2 arguments, but got 5. fs2('a', 'b', 'c', ...s2, 'd'); // error on 'c', ...s2 and 'd' ~~~~~~~~~~~~~~~ -!!! error TS2556: Expected 2 arguments, but got 5 or more. +!!! error TS2554: Expected 2 arguments, but got 6. fs2(...s2, 'a'); // error on 'a' ~~~ -!!! error TS2556: Expected 2 arguments, but got 1 or more. -!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts:8:33: An argument for 'b' was not provided. +!!! error TS2554: Expected 2 arguments, but got 3. fs2(...s3); // error on ...s3 ~~~~~ !!! error TS2554: Expected 2 arguments, but got 3. @@ -68,6 +68,8 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread3.ts(25,7): erro fs2_(...s2_, ...s_); fs2_(...s2_, ...s2_); fs2_(...s_, ...s2_); + ~~~~~~ +!!! error TS2557: Expected at least 2 arguments, but got 4 or more. fs2n_(...s2n_); fs2n_(...s2); // fs2n_(...s2, ...n_); // FIXME: should compile diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index 0a1d592e8b1cf..e062d4332597b 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -1,11 +1,10 @@ tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. - Property '2' is missing in type '[number, string]' but required in type '[number, string, boolean]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Conversion of type '[number, string, boolean]' to type '[number, string]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. - Types of property 'length' are incompatible. - Type '3' is not comparable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. - Property '2' is missing in type '[C, D]' but required in type '[C, D, A]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2493: Tuple type '[C, D, A]' of length '3' has no element at index '5'. tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type 'string' is not comparable to type 'number'. @@ -31,12 +30,11 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot var numStrBoolTuple = <[number, string, boolean]>numStrTuple; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. -!!! error TS2352: Property '2' is missing in type '[number, string]' but required in type '[number, string, boolean]'. +!!! error TS2352: Source has 2 element(s) but target requires 3. var shorter = numStrBoolTuple as [number, string] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Conversion of type '[number, string, boolean]' to type '[number, string]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. -!!! error TS2352: Types of property 'length' are incompatible. -!!! error TS2352: Type '3' is not comparable to type '2'. +!!! error TS2352: Source has 3 element(s) but target allows only 2. var longer = numStrTuple as [number, string, boolean] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. @@ -45,7 +43,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot var classCDATuple = <[C, D, A]>classCDTuple; ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. -!!! error TS2352: Property '2' is missing in type '[C, D]' but required in type '[C, D, A]'. +!!! error TS2352: Source has 2 element(s) but target requires 3. var eleFromCDA1 = classCDATuple[2]; // A var eleFromCDA2 = classCDATuple[5]; // C | D | A ~ diff --git a/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt b/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt index 0780f4e92c181..e003223fd1d9f 100644 --- a/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): ResizablePanel', gave the following error. Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. - The types of 'children.length' are incompatible between these types. - Type '3' is not assignable to type '2'. + Types of property 'children' are incompatible. + Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'. + Source has 3 element(s) but target allows only 2. Overload 2 of 2, '(props: ResizablePanelProps, context?: any): ResizablePanel', gave the following error. Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. Types of property 'children' are incompatible. @@ -31,8 +32,9 @@ tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2 !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(props: Readonly): ResizablePanel', gave the following error. !!! error TS2769: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. -!!! error TS2769: The types of 'children.length' are incompatible between these types. -!!! error TS2769: Type '3' is not assignable to type '2'. +!!! error TS2769: Types of property 'children' are incompatible. +!!! error TS2769: Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'. +!!! error TS2769: Source has 3 element(s) but target allows only 2. !!! error TS2769: Overload 2 of 2, '(props: ResizablePanelProps, context?: any): ResizablePanel', gave the following error. !!! error TS2769: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. !!! error TS2769: Types of property 'children' are incompatible. diff --git a/tests/baselines/reference/compoundAssignmentLHSIsValue.types b/tests/baselines/reference/compoundAssignmentLHSIsValue.types index 5aafaa2647c64..1b29281e03ec6 100644 --- a/tests/baselines/reference/compoundAssignmentLHSIsValue.types +++ b/tests/baselines/reference/compoundAssignmentLHSIsValue.types @@ -432,14 +432,14 @@ foo() += value; ([]) *= value; >([]) *= value : number ->([]) : undefined[] ->[] : undefined[] +>([]) : [] +>[] : [] >value : any ([]) += value; >([]) += value : any ->([]) : undefined[] ->[] : undefined[] +>([]) : [] +>[] : [] >value : any (function baz1() { }) *= value; diff --git a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.types b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.types index 58ec77add862e..bcabf2c761633 100644 --- a/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.types +++ b/tests/baselines/reference/compoundExponentiationAssignmentLHSIsValue.types @@ -244,8 +244,8 @@ foo() **= value; ([]) **= value; >([]) **= value : number ->([]) : undefined[] ->[] : undefined[] +>([]) : [] +>[] : [] >value : any (function baz1() { }) **= value; diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt index d479211935212..4a248485a0e93 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.errors.txt +++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt @@ -1,18 +1,16 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(3,5): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(15,1): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,17): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: string; }'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(19,1): error TS2741: Property '2' is missing in type '[number, string]' but required in type '[number, string, boolean]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(19,1): error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(20,5): error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(23,1): error TS2322: Type '[C, string | number, D]' is not assignable to type '[C, string | number]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2741: Property '2' is missing in type '[C, string | number]' but required in type '[C, string | number, D]'. + Source has 3 element(s) but target allows only 2. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. @@ -24,8 +22,7 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23 var numStrTuple2: [number, string] = [5, "foo", true]; ~~~~~~~~~~~~ !!! error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '3' is not assignable to type '2'. +!!! error TS2322: Source has 3 element(s) but target allows only 2. var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; @@ -40,8 +37,7 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23 numStrTuple = numStrBoolTuple; ~~~~~~~~~~~ !!! error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '3' is not assignable to type '2'. +!!! error TS2322: Source has 3 element(s) but target allows only 2. // error objNumTuple = [ {}, 5]; @@ -50,22 +46,22 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS23 !!! related TS2728 tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts:5:21: 'a' is declared here. numStrBoolTuple = numStrTuple; ~~~~~~~~~~~~~~~ -!!! error TS2741: Property '2' is missing in type '[number, string]' but required in type '[number, string, boolean]'. +!!! error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]'. +!!! error TS2322: Source has 2 element(s) but target requires 3. var strStrTuple: [string, string] = ["foo", "bar", 5]; ~~~~~~~~~~~ !!! error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '3' is not assignable to type '2'. +!!! error TS2322: Source has 3 element(s) but target allows only 2. unionTuple = unionTuple1; unionTuple = unionTuple2; ~~~~~~~~~~ !!! error TS2322: Type '[C, string | number, D]' is not assignable to type '[C, string | number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '3' is not assignable to type '2'. +!!! error TS2322: Source has 3 element(s) but target allows only 2. unionTuple2 = unionTuple; ~~~~~~~~~~~ -!!! error TS2741: Property '2' is missing in type '[C, string | number]' but required in type '[C, string | number, D]'. +!!! error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. +!!! error TS2322: Source has 2 element(s) but target requires 3. numStrTuple = unionTuple3; ~~~~~~~~~~~ !!! error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. diff --git a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt index dd01ac9651928..49493f444402c 100644 --- a/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt +++ b/tests/baselines/reference/destructuringArrayBindingPatternAndAssignment2.errors.txt @@ -4,8 +4,10 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(3,12): error TS2493: Tuple type '[]' of length '0' has no element at index '1'. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(4,5): error TS2461: Type 'undefined' is not an array type. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(9,51): error TS2322: Type 'number' is not assignable to type 'boolean'. -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(22,5): error TS2739: Type 'number[]' is missing the following properties from type '[number, number]': 0, 1 -tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(23,5): error TS2739: Type 'number[]' is missing the following properties from type '[string, string]': 0, 1 +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(22,5): error TS2322: Type 'number[]' is not assignable to type '[number, number]'. + Target requires 2 element(s) but source may have fewer. +tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(23,5): error TS2322: Type 'number[]' is not assignable to type '[string, string]'. + Target requires 2 element(s) but source may have fewer. tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment2.ts(34,5): error TS2461: Type 'F' is not an array type. @@ -45,10 +47,12 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss var temp = [1, 2, 3] var [c0, c1]: [number, number] = [...temp]; // Error ~~~~~~~~ -!!! error TS2739: Type 'number[]' is missing the following properties from type '[number, number]': 0, 1 +!!! error TS2322: Type 'number[]' is not assignable to type '[number, number]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. var [c2, c3]: [string, string] = [...temp]; // Error ~~~~~~~~ -!!! error TS2739: Type 'number[]' is missing the following properties from type '[string, string]': 0, 1 +!!! error TS2322: Type 'number[]' is not assignable to type '[string, string]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. interface F { [idx: number]: boolean diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt index fbbfc3b0d218d..a5f4668d89376 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5.errors.txt @@ -1,9 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(12,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(57,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property 'length' are incompatible. - Type '5' is not assignable to type '3'. + Source has 5 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(62,10): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(63,10): error TS2393: Duplicate function implementation. @@ -23,8 +21,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5. a1([1, 2, [["world"]], 3]); ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '4' is not assignable to type '3'. +!!! error TS2345: Source has 4 element(s) but target allows only 3. // If the declaration includes an initializer expression (which is permitted only // when the parameter list occurs in conjunction with a function body), @@ -72,8 +69,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5. c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '5' is not assignable to type '3'. +!!! error TS2345: Source has 5 element(s) but target allows only 3. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) // or by including an initializer. diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt index 1dc3c61bb3a6e..f6a65806e3beb 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES5iterable.errors.txt @@ -1,9 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(12,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(57,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property 'length' are incompatible. - Type '5' is not assignable to type '3'. + Source has 5 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(62,10): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5iterable.ts(63,10): error TS2393: Duplicate function implementation. @@ -23,8 +21,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5i a1([1, 2, [["world"]], 3]); ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '4' is not assignable to type '3'. +!!! error TS2345: Source has 4 element(s) but target allows only 3. // If the declaration includes an initializer expression (which is permitted only // when the parameter list occurs in conjunction with a function body), @@ -72,8 +69,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5i c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '5' is not assignable to type '3'. +!!! error TS2345: Source has 5 element(s) but target allows only 3. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) // or by including an initializer. diff --git a/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt index f6c17a5c0ea6e..3b7c2dfa30616 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration1ES6.errors.txt @@ -1,9 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(14,4): error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(58,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property 'length' are incompatible. - Type '5' is not assignable to type '3'. + Source has 5 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,18): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,26): error TS2300: Duplicate identifier 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6.ts(96,34): error TS2300: Duplicate identifier 'number'. @@ -26,8 +24,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6. a1([1, 2, [["world"]], 3]); ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], number]' is not assignable to parameter of type '[number, number, string[][]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '4' is not assignable to type '3'. +!!! error TS2345: Source has 4 element(s) but target allows only 3. // If the declaration includes an initializer expression (which is permitted only @@ -74,8 +71,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES6. c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '5' is not assignable to type '3'. +!!! error TS2345: Source has 5 element(s) but target allows only 3. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 12beead1afb2a..c1c79a2300d26 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -1,8 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,8): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,29): error TS1005: ',' expected. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(8,4): error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '3'. + Source has 4 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,8): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,16): error TS2322: Type 'string' is not assignable to type 'number'. @@ -43,8 +42,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( a0([1, 2, [["world"]], "string"]); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '4' is not assignable to type '3'. +!!! error TS2345: Source has 4 element(s) but target allows only 3. // If the declaration includes an initializer expression (which is permitted only diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt index bb8b5fe8eb240..fec2abc9a9eeb 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property 'length' are incompatible. - Type '5' is not assignable to type '3'. + Source has 5 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. - Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]], ...any[]]'. + Source has 2 element(s) but target requires 3. ==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts (3 errors) ==== @@ -35,8 +34,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5. a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '5' is not assignable to type '3'. +!!! error TS2345: Source has 5 element(s) but target allows only 3. a10([1, 2, [["string"]], false, true]); // Parameter type is any[] a10([1, 2, 3, false, true]); // Parameter type is any[] @@ -45,7 +43,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5. a10([1, 2]); // Parameter type is any[] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. -!!! error TS2345: Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]], ...any[]]'. +!!! error TS2345: Source has 2 element(s) but target requires 3. a11([1, 2]); // Parameter type is number[] // Rest parameter with generic diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt index ed67aa9cf2157..9e4ccf8100027 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property 'length' are incompatible. - Type '5' is not assignable to type '3'. + Source has 5 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. - Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]], ...any[]]'. + Source has 2 element(s) but target requires 3. ==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts (3 errors) ==== @@ -35,8 +34,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5i a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '5' is not assignable to type '3'. +!!! error TS2345: Source has 5 element(s) but target allows only 3. a10([1, 2, [["string"]], false, true]); // Parameter type is any[] a10([1, 2, 3, false, true]); // Parameter type is any[] @@ -45,7 +43,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5i a10([1, 2]); // Parameter type is any[] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. -!!! error TS2345: Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]], ...any[]]'. +!!! error TS2345: Source has 2 element(s) but target requires 3. a11([1, 2]); // Parameter type is number[] // Rest parameter with generic diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt index d79be518a2488..d3e072686d82c 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt @@ -1,9 +1,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property 'length' are incompatible. - Type '5' is not assignable to type '3'. + Source has 5 element(s) but target allows only 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. - Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]], ...any[]]'. + Source has 2 element(s) but target requires 3. ==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts (3 errors) ==== @@ -35,8 +34,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6. a9([1, 2, [["string"]], false, true]); // Parameter type is [any, any, [[any]]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '5' is not assignable to type '3'. +!!! error TS2345: Source has 5 element(s) but target allows only 3. a10([1, 2, [["string"]], false, true]); // Parameter type is any[] a10([1, 2, 3, false, true]); // Parameter type is any[] @@ -45,7 +43,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6. a10([1, 2]); // Parameter type is any[] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. -!!! error TS2345: Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]], ...any[]]'. +!!! error TS2345: Source has 2 element(s) but target requires 3. a11([1, 2]); // Parameter type is number[] // Rest parameter with generic diff --git a/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt index e6a1c559a13b0..d3e198c87149a 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt @@ -4,7 +4,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts( tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(21,7): error TS2552: Cannot find name 'array2'. Did you mean 'Array'? tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(22,11): error TS2322: Type 'string' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(23,4): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]]]'. - Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]]]'. + Source has 2 element(s) but target requires 3. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(24,11): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(29,17): error TS1317: A parameter property cannot be declared using a rest parameter. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(34,22): error TS2304: Cannot find name 'E1'. @@ -48,7 +48,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts( a5([1, 2]); // Error, parameter type is [any, any, [[any]]] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Property '2' is missing in type '[number, number]' but required in type '[any, any, [[any]]]'. +!!! error TS2345: Source has 2 element(s) but target requires 3. a6([1, 2, "string"]); // Error, parameter type is number[] ~~~~~~~~ !!! error TS2322: Type 'string' is not assignable to type 'number'. diff --git a/tests/baselines/reference/destructuringTuple.errors.txt b/tests/baselines/reference/destructuringTuple.errors.txt index e6c7815968b1a..31ffdac62200a 100644 --- a/tests/baselines/reference/destructuringTuple.errors.txt +++ b/tests/baselines/reference/destructuringTuple.errors.txt @@ -4,8 +4,7 @@ tests/cases/compiler/destructuringTuple.ts(11,48): error TS2769: No overload mat Type 'never[]' is not assignable to type 'number'. Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error. Type 'never[]' is not assignable to type '[]'. - Types of property 'length' are incompatible. - Type 'number' is not assignable to type '0'. + Target allows only 0 element(s) but source may have more. tests/cases/compiler/destructuringTuple.ts(11,60): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. @@ -33,8 +32,7 @@ tests/cases/compiler/destructuringTuple.ts(11,60): error TS2769: No overload mat !!! error TS2769: Type 'never[]' is not assignable to type 'number'. !!! error TS2769: Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error. !!! error TS2769: Type 'never[]' is not assignable to type '[]'. -!!! error TS2769: Types of property 'length' are incompatible. -!!! error TS2769: Type 'number' is not assignable to type '0'. +!!! error TS2769: Target allows only 0 element(s) but source may have more. !!! related TS6502 /.ts/lib.es5.d.ts:1368:24: The expected type comes from the return type of this signature. !!! related TS6502 /.ts/lib.es5.d.ts:1374:27: The expected type comes from the return type of this signature. ~~ diff --git a/tests/baselines/reference/elementAccessChain.3.types b/tests/baselines/reference/elementAccessChain.3.types index d0d00ffea7193..b1f1e431a614b 100644 --- a/tests/baselines/reference/elementAccessChain.3.types +++ b/tests/baselines/reference/elementAccessChain.3.types @@ -170,7 +170,7 @@ for (obj?.a["b"] of []); [...obj?.["a"]] = []; >[...obj?.["a"]] = [] : never[] ->[...obj?.["a"]] : never[] +>[...obj?.["a"]] : any[] >...obj?.["a"] : any >obj?.["a"] : any >obj : any @@ -179,7 +179,7 @@ for (obj?.a["b"] of []); [...obj?.a["b"]] = []; >[...obj?.a["b"]] = [] : never[] ->[...obj?.a["b"]] : never[] +>[...obj?.a["b"]] : any[] >...obj?.a["b"] : any >obj?.a["b"] : any >obj?.a : any diff --git a/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types index 450a24a0fa74c..f779a5abc9b8e 100644 --- a/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types +++ b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types @@ -2,7 +2,7 @@ var a = [] = [1].map(_ => _); >a : number[] >[] = [1].map(_ => _) : number[] ->[] : undefined[] +>[] : [] >[1].map(_ => _) : number[] >[1].map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] >[1] : number[] diff --git a/tests/baselines/reference/emptyAssignmentPatterns01_ES5.types b/tests/baselines/reference/emptyAssignmentPatterns01_ES5.types index a744a190d036b..ddcffe5b076b9 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns01_ES5.types +++ b/tests/baselines/reference/emptyAssignmentPatterns01_ES5.types @@ -11,7 +11,7 @@ var a: any; ([] = a); >([] = a) : any >[] = a : any ->[] : undefined[] +>[] : [] >a : any var [,] = [1,2]; diff --git a/tests/baselines/reference/emptyAssignmentPatterns01_ES5iterable.types b/tests/baselines/reference/emptyAssignmentPatterns01_ES5iterable.types index 4f60d19cfd1ee..3de19851f3024 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns01_ES5iterable.types +++ b/tests/baselines/reference/emptyAssignmentPatterns01_ES5iterable.types @@ -11,6 +11,6 @@ var a: any; ([] = a); >([] = a) : any >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns01_ES6.types b/tests/baselines/reference/emptyAssignmentPatterns01_ES6.types index 770547f9e7bc2..f9bd2041a510c 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns01_ES6.types +++ b/tests/baselines/reference/emptyAssignmentPatterns01_ES6.types @@ -11,6 +11,6 @@ var a: any; ([] = a); >([] = a) : any >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns02_ES5.types b/tests/baselines/reference/emptyAssignmentPatterns02_ES5.types index 383afeb7c9d16..df436870a8f8e 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns02_ES5.types +++ b/tests/baselines/reference/emptyAssignmentPatterns02_ES5.types @@ -24,7 +24,7 @@ let x, y, z, a1, a2, a3; ([] = [ a1, a2, a3] = a); >([] = [ a1, a2, a3] = a) : any >[] = [ a1, a2, a3] = a : any ->[] : undefined[] +>[] : [] >[ a1, a2, a3] = a : any >[ a1, a2, a3] : [any, any, any] >a1 : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns02_ES5iterable.types b/tests/baselines/reference/emptyAssignmentPatterns02_ES5iterable.types index e75fca12e0f6b..cf7d38fbb449f 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns02_ES5iterable.types +++ b/tests/baselines/reference/emptyAssignmentPatterns02_ES5iterable.types @@ -24,7 +24,7 @@ let x, y, z, a1, a2, a3; ([] = [ a1, a2, a3] = a); >([] = [ a1, a2, a3] = a) : any >[] = [ a1, a2, a3] = a : any ->[] : undefined[] +>[] : [] >[ a1, a2, a3] = a : any >[ a1, a2, a3] : [any, any, any] >a1 : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns02_ES6.types b/tests/baselines/reference/emptyAssignmentPatterns02_ES6.types index b62aba04e7cd6..7634605894d9e 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns02_ES6.types +++ b/tests/baselines/reference/emptyAssignmentPatterns02_ES6.types @@ -24,7 +24,7 @@ let x, y, z, a1, a2, a3; ([] = [ a1, a2, a3] = a); >([] = [ a1, a2, a3] = a) : any >[] = [ a1, a2, a3] = a : any ->[] : undefined[] +>[] : [] >[ a1, a2, a3] = a : any >[ a1, a2, a3] : [any, any, any] >a1 : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns03_ES5.types b/tests/baselines/reference/emptyAssignmentPatterns03_ES5.types index 76c63ca761cae..e86429eb1d776 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns03_ES5.types +++ b/tests/baselines/reference/emptyAssignmentPatterns03_ES5.types @@ -13,8 +13,8 @@ var a: any; ([] = [] = a); >([] = [] = a) : any >[] = [] = a : any ->[] : undefined[] +>[] : [] >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns03_ES5iterable.types b/tests/baselines/reference/emptyAssignmentPatterns03_ES5iterable.types index 5e7b867f44b2e..da71fee91f259 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns03_ES5iterable.types +++ b/tests/baselines/reference/emptyAssignmentPatterns03_ES5iterable.types @@ -13,8 +13,8 @@ var a: any; ([] = [] = a); >([] = [] = a) : any >[] = [] = a : any ->[] : undefined[] +>[] : [] >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns03_ES6.types b/tests/baselines/reference/emptyAssignmentPatterns03_ES6.types index 9e826e4b92b93..d2c0b4fad212e 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns03_ES6.types +++ b/tests/baselines/reference/emptyAssignmentPatterns03_ES6.types @@ -13,8 +13,8 @@ var a: any; ([] = [] = a); >([] = [] = a) : any >[] = [] = a : any ->[] : undefined[] +>[] : [] >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns04_ES5.types b/tests/baselines/reference/emptyAssignmentPatterns04_ES5.types index 0c8672917774b..fc69f1faba285 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns04_ES5.types +++ b/tests/baselines/reference/emptyAssignmentPatterns04_ES5.types @@ -29,6 +29,6 @@ let x, y, z, a1, a2, a3; >a2 : any >a3 : any >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns04_ES5iterable.types b/tests/baselines/reference/emptyAssignmentPatterns04_ES5iterable.types index cfd3991852ce5..8cf3ba5dd2e18 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns04_ES5iterable.types +++ b/tests/baselines/reference/emptyAssignmentPatterns04_ES5iterable.types @@ -29,6 +29,6 @@ let x, y, z, a1, a2, a3; >a2 : any >a3 : any >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/emptyAssignmentPatterns04_ES6.types b/tests/baselines/reference/emptyAssignmentPatterns04_ES6.types index d92c91b057621..1079fc297669b 100644 --- a/tests/baselines/reference/emptyAssignmentPatterns04_ES6.types +++ b/tests/baselines/reference/emptyAssignmentPatterns04_ES6.types @@ -29,6 +29,6 @@ let x, y, z, a1, a2, a3; >a2 : any >a3 : any >[] = a : any ->[] : undefined[] +>[] : [] >a : any diff --git a/tests/baselines/reference/genericCallWithTupleType.errors.txt b/tests/baselines/reference/genericCallWithTupleType.errors.txt index 0cc4a4986db31..8da102727c2f8 100644 --- a/tests/baselines/reference/genericCallWithTupleType.errors.txt +++ b/tests/baselines/reference/genericCallWithTupleType.errors.txt @@ -1,6 +1,5 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(12,1): error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'. - Types of property 'length' are incompatible. - Type '4' is not assignable to type '2'. + Source has 4 element(s) but target allows only 2. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(13,20): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'undefined'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,11): error TS2493: Tuple type '[string, number]' of length '2' has no element at index '3'. @@ -9,7 +8,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,17): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(23,14): error TS2322: Type '{}' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(23,18): error TS2322: Type '{}' is not assignable to type 'number'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(24,1): error TS2741: Property '1' is missing in type '[{}]' but required in type '[{}, {}]'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(24,1): error TS2322: Type '[{}]' is not assignable to type '[{}, {}]'. + Source has 1 element(s) but target requires 2. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts (10 errors) ==== @@ -27,8 +27,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup i1.tuple1 = ["foo", 5, false, true]; ~~~~~~~~~ !!! error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '4' is not assignable to type '2'. +!!! error TS2322: Source has 4 element(s) but target allows only 2. var e3 = i1.tuple1[2]; // {} ~ !!! error TS2493: Tuple type '[string, number]' of length '2' has no element at index '2'. @@ -58,5 +57,6 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup !!! error TS2322: Type '{}' is not assignable to type 'number'. i2.tuple1 = [{}]; ~~~~~~~~~ -!!! error TS2741: Property '1' is missing in type '[{}]' but required in type '[{}, {}]'. +!!! error TS2322: Type '[{}]' is not assignable to type '[{}, {}]'. +!!! error TS2322: Source has 1 element(s) but target requires 2. \ No newline at end of file diff --git a/tests/baselines/reference/genericRestParameters1.errors.txt b/tests/baselines/reference/genericRestParameters1.errors.txt index 707e86a94dd8f..b3d13ab2f652d 100644 --- a/tests/baselines/reference/genericRestParameters1.errors.txt +++ b/tests/baselines/reference/genericRestParameters1.errors.txt @@ -1,7 +1,3 @@ -tests/cases/conformance/types/rest/genericRestParameters1.ts(22,4): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/rest/genericRestParameters1.ts(31,4): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. - Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. Type 'Function' provides no match for the signature '(...args: any): any'. tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. @@ -9,7 +5,7 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 Type 'any' is not assignable to type 'never'. -==== tests/cases/conformance/types/rest/genericRestParameters1.ts (4 errors) ==== +==== tests/cases/conformance/types/rest/genericRestParameters1.ts (2 errors) ==== declare let f1: (...x: [number, string, boolean]) => void; declare let f2: (x0: number, x1: string, x2: boolean) => void; @@ -32,9 +28,6 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 f1(42, "hello", true, ...t0); f1(ns[0], ns[1], true); f1(...ns, true); // FIXME: Error, since ...ns is considered as string|number here - ~~~~~ -!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. -!!! error TS2345: Type 'string' is not assignable to type 'number'. f2(42, "hello", true); f2(t3[0], t3[1], t3[2]); @@ -44,9 +37,6 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 f2(42, "hello", true, ...t0); f2(ns[0], ns[1], true); f2(...ns, true); // FIXME: Error, since ...ns is considered as string|number here - ~~~~~ -!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'. -!!! error TS2345: Type 'string' is not assignable to type 'number'. declare function f10(...args: T): T; diff --git a/tests/baselines/reference/genericRestParameters1.js b/tests/baselines/reference/genericRestParameters1.js index 0e094d0f288fd..435557a817500 100644 --- a/tests/baselines/reference/genericRestParameters1.js +++ b/tests/baselines/reference/genericRestParameters1.js @@ -296,7 +296,7 @@ declare const x14: [number, string, boolean]; declare const x15: [number, string, boolean]; declare const x16: [number, string, boolean]; declare const x17: [number, string, boolean]; -declare const x18: (string | number | boolean)[]; +declare const x18: [number, string, boolean]; declare function g10(u: U, v: V): void; declare function f11(...args: T): T; declare const z10: [42, "hello", true]; @@ -307,7 +307,7 @@ declare const z14: [number, string, boolean]; declare const z15: [42, string, boolean]; declare const z16: [42, "hello", boolean]; declare const z17: [42, "hello", true]; -declare const z18: (string | number | true)[]; +declare const z18: [number, string, true]; declare function g11(u: U, v: V): void; declare function call(f: (...args: T) => U, ...args: T): U; declare function callr(args: T, f: (...args: T) => U): U; diff --git a/tests/baselines/reference/genericRestParameters1.types b/tests/baselines/reference/genericRestParameters1.types index 6dfee15241288..89352e1fab239 100644 --- a/tests/baselines/reference/genericRestParameters1.types +++ b/tests/baselines/reference/genericRestParameters1.types @@ -238,8 +238,8 @@ const x17 = f10(42, "hello", true, ...t0); // [number, string, boolean] >t0 : [] const x18 = f10(...ns, true); // (string | number | boolean)[] ->x18 : (string | number | boolean)[] ->f10(...ns, true) : (string | number | boolean)[] +>x18 : [number, string, boolean] +>f10(...ns, true) : [number, string, boolean] >f10 : (...args: T) => T >...ns : string | number >ns : [number, string] @@ -265,16 +265,16 @@ function g10(u: U, v: V) { >v : V let x3 = f10(1, ...u); // [number, ...string[]] ->x3 : [number, ...string[]] ->f10(1, ...u) : [number, ...string[]] +>x3 : [number, ...U] +>f10(1, ...u) : [number, ...U] >f10 : (...args: T) => T >1 : 1 >...u : string >u : U let x4 = f10(...u, ...v); // (string | number)[] ->x4 : (string | number)[] ->f10(...u, ...v) : (string | number)[] +>x4 : [...U, ...V] +>f10(...u, ...v) : [...U, ...V] >f10 : (...args: T) => T >...u : string >u : U @@ -347,8 +347,8 @@ const z17 = f11(42, "hello", true, ...t0); // [42, "hello", true] >t0 : [] const z18 = f11(...ns, true); // (string | number | true)[] ->z18 : (string | number | true)[] ->f11(...ns, true) : (string | number | true)[] +>z18 : [number, string, true] +>f11(...ns, true) : [number, string, true] >f11 : (...args: T) => T >...ns : string | number >ns : [number, string] @@ -374,16 +374,16 @@ function g11(u: U, v: V) { >v : V let x3 = f11(1, ...u); // [1, ...string[]] ->x3 : [1, ...string[]] ->f11(1, ...u) : [1, ...string[]] +>x3 : [1, ...U] +>f11(1, ...u) : [1, ...U] >f11 : (...args: T) => T >1 : 1 >...u : string >u : U let x4 = f11(...u, ...v); // (string | number)[] ->x4 : (string | number)[] ->f11(...u, ...v) : (string | number)[] +>x4 : [...U, ...V] +>f11(...u, ...v) : [...U, ...V] >f11 : (...args: T) => T >...u : string >u : U diff --git a/tests/baselines/reference/genericRestParameters2.types b/tests/baselines/reference/genericRestParameters2.types index ec17e78625209..9c5bcce5212f4 100644 --- a/tests/baselines/reference/genericRestParameters2.types +++ b/tests/baselines/reference/genericRestParameters2.types @@ -408,7 +408,7 @@ f20(42, "hello", ...t3); >t3 : boolean[] f20(42, "hello", ...t2, true); ->f20(42, "hello", ...t2, true) : [number, string, ...(string | boolean)[]] +>f20(42, "hello", ...t2, true) : [number, string, string, ...boolean[]] >f20 : (...args: T) => T >42 : 42 >"hello" : "hello" @@ -437,7 +437,7 @@ type T04 = ConstructorParametersargs : [number, string, ...boolean[]] type T05 = Parameters<(x: string, ...args: T) => void>; ->T05 : Parameters<(x: string, ...args: T) => void> +>T05 : [x: string, ...args: T] >x : string >args : T diff --git a/tests/baselines/reference/genericRestParameters3.errors.txt b/tests/baselines/reference/genericRestParameters3.errors.txt index 66ccadc2f1f34..72620c41027dc 100644 --- a/tests/baselines/reference/genericRestParameters3.errors.txt +++ b/tests/baselines/reference/genericRestParameters3.errors.txt @@ -2,18 +2,19 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(17,11): error TS234 Type '[10]' is not assignable to type '[string]'. Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'. - Type '[]' is missing the following properties from type '[number, boolean]': 0, 1 + Type '[]' is not assignable to type '[number, boolean]'. + Source has 0 element(s) but target requires 2. tests/cases/conformance/types/rest/genericRestParameters3.ts(22,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'. tests/cases/conformance/types/rest/genericRestParameters3.ts(23,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. Types of parameters 'y' and 'args' are incompatible. Type '[string] | [number, boolean]' is not assignable to type '[y: string]'. Type '[number, boolean]' is not assignable to type '[y: string]'. - Types of property '0' are incompatible. - Type 'number' is not assignable to type 'string'. + Source has 2 element(s) but target allows only 1. tests/cases/conformance/types/rest/genericRestParameters3.ts(24,1): error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. Types of parameters 'y' and 'args' are incompatible. Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'. - Property '1' is missing in type '[string]' but required in type '[y: number, z: boolean]'. + Type '[string]' is not assignable to type '[y: number, z: boolean]'. + Source has 1 element(s) but target requires 2. tests/cases/conformance/types/rest/genericRestParameters3.ts(25,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. tests/cases/conformance/types/rest/genericRestParameters3.ts(35,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/rest/genericRestParameters3.ts(36,21): error TS2345: Argument of type 'number' is not assignable to parameter of type '(...args: CoolArray) => void'. @@ -31,7 +32,8 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(51,5): error TS2345 tests/cases/conformance/types/rest/genericRestParameters3.ts(52,5): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray'. Property 'hello' is missing in type 'number[]' but required in type 'CoolArray'. tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'. - Property '1' is missing in type '["what"]' but required in type '[number, string]'. + Type '["what"]' is not assignable to type '[number, string]'. + Source has 1 element(s) but target requires 2. ==== tests/cases/conformance/types/rest/genericRestParameters3.ts (15 errors) ==== @@ -59,7 +61,8 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 f1("foo"); // Error ~~~~~~~~~ !!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'. -!!! error TS2345: Type '[]' is missing the following properties from type '[number, boolean]': 0, 1 +!!! error TS2345: Type '[]' is not assignable to type '[number, boolean]'. +!!! error TS2345: Source has 0 element(s) but target requires 2. f2 = f1; f3 = f1; @@ -72,14 +75,14 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 !!! error TS2322: Types of parameters 'y' and 'args' are incompatible. !!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: string]'. !!! error TS2322: Type '[number, boolean]' is not assignable to type '[y: string]'. -!!! error TS2322: Types of property '0' are incompatible. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Source has 2 element(s) but target allows only 1. f1 = f3; // Error ~~ !!! error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. !!! error TS2322: Types of parameters 'y' and 'args' are incompatible. !!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'. -!!! error TS2322: Property '1' is missing in type '[string]' but required in type '[y: number, z: boolean]'. +!!! error TS2322: Type '[string]' is not assignable to type '[y: number, z: boolean]'. +!!! error TS2322: Source has 1 element(s) but target requires 2. f1 = f4; // Error, misaligned complex rest types ~~ !!! error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. @@ -148,7 +151,8 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 hmm("what"); // no error? A = [] | [number, string] ? ~~~~~~ !!! error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'. -!!! error TS2345: Property '1' is missing in type '["what"]' but required in type '[number, string]'. +!!! error TS2345: Type '["what"]' is not assignable to type '[number, string]'. +!!! error TS2345: Source has 1 element(s) but target requires 2. // Repro from #35066 diff --git a/tests/baselines/reference/genericRestTypes.errors.txt b/tests/baselines/reference/genericRestTypes.errors.txt index 0df6490b6a22d..bcb90b32731d1 100644 --- a/tests/baselines/reference/genericRestTypes.errors.txt +++ b/tests/baselines/reference/genericRestTypes.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/genericRestTypes.ts(21,11): error TS2322: Type '(cb: (x: string, ...rest: T) => void) => void' is not assignable to type '(cb: (...args: never) => void) => void'. Types of parameters 'cb' and 'cb' are incompatible. Types of parameters 'args' and 'x' are incompatible. - Type '[x: string, ...rest: T[number][]]' is not assignable to type 'never'. + Type '[x: string, ...rest: T]' is not assignable to type 'never'. ==== tests/cases/compiler/genericRestTypes.ts (1 errors) ==== @@ -30,7 +30,7 @@ tests/cases/compiler/genericRestTypes.ts(21,11): error TS2322: Type '(cb: (x: st !!! error TS2322: Type '(cb: (x: string, ...rest: T) => void) => void' is not assignable to type '(cb: (...args: never) => void) => void'. !!! error TS2322: Types of parameters 'cb' and 'cb' are incompatible. !!! error TS2322: Types of parameters 'args' and 'x' are incompatible. -!!! error TS2322: Type '[x: string, ...rest: T[number][]]' is not assignable to type 'never'. +!!! error TS2322: Type '[x: string, ...rest: T]' is not assignable to type 'never'. } function assignmentWithComplexRest3() { diff --git a/tests/baselines/reference/namedTupleMembersErrors.errors.txt b/tests/baselines/reference/namedTupleMembersErrors.errors.txt index 19e40ba93719a..af37194d193c7 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.errors.txt +++ b/tests/baselines/reference/namedTupleMembersErrors.errors.txt @@ -7,8 +7,8 @@ tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(11,49): err tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(11,52): error TS8020: JSDoc types can only be used inside documentation comments. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(13,39): error TS5085: A tuple member cannot be both optional and rest. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(15,44): error TS2574: A rest element type must be an array type. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(17,46): error TS2574: A rest element type must be an array type. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(18,44): error TS2574: A rest element type must be an array type. +tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(17,13): error TS2456: Type alias 'RecusiveRestUnlabeled' circularly references itself. +tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(18,13): error TS2456: Type alias 'RecusiveRest' circularly references itself. ==== tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts (11 errors) ==== @@ -47,9 +47,9 @@ tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(18,44): err !!! error TS2574: A rest element type must be an array type. export type RecusiveRestUnlabeled = [string, ...RecusiveRestUnlabeled]; - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2574: A rest element type must be an array type. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2456: Type alias 'RecusiveRestUnlabeled' circularly references itself. export type RecusiveRest = [first: string, ...rest: RecusiveRest]; // marked as incorrect, same as above - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2574: A rest element type must be an array type. + ~~~~~~~~~~~~ +!!! error TS2456: Type alias 'RecusiveRest' circularly references itself. \ No newline at end of file diff --git a/tests/baselines/reference/namedTupleMembersErrors.types b/tests/baselines/reference/namedTupleMembersErrors.types index 3285a453592ba..761437dac55d7 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.types +++ b/tests/baselines/reference/namedTupleMembersErrors.types @@ -3,7 +3,7 @@ export type Segment1 = [length: number, number]; // partially named, disallowed >Segment1 : Segment1 export type List = [item: any, ...any]; // partially named, disallowed ->List : List +>List : [any, ...any[]] export type Pair = [item: any, any?]; // partially named, disallowed >Pair : Pair @@ -21,11 +21,11 @@ export type OptRest = [first: string, ...rest?: string[]]; // rest+optional disa >OptRest : OptRest export type NonArrayRest = [first: string, ...rest: number]; // non-arraylike rest, disallowed ->NonArrayRest : NonArrayRest +>NonArrayRest : [first: string, ...rest: any[]] export type RecusiveRestUnlabeled = [string, ...RecusiveRestUnlabeled]; ->RecusiveRestUnlabeled : RecusiveRestUnlabeled +>RecusiveRestUnlabeled : any export type RecusiveRest = [first: string, ...rest: RecusiveRest]; // marked as incorrect, same as above ->RecusiveRest : RecusiveRest +>RecusiveRest : any diff --git a/tests/baselines/reference/namespaceDisambiguationInUnion.errors.txt b/tests/baselines/reference/namespaceDisambiguationInUnion.errors.txt index 1f2a8ab69cea9..52b34b1b59058 100644 --- a/tests/baselines/reference/namespaceDisambiguationInUnion.errors.txt +++ b/tests/baselines/reference/namespaceDisambiguationInUnion.errors.txt @@ -2,7 +2,8 @@ tests/cases/compiler/namespaceDisambiguationInUnion.ts(10,7): error TS2322: Type Type '{ type: string; }' is not assignable to type 'Yep'. Types of property 'type' are incompatible. Type 'string' is not assignable to type '"bar.yep"'. -tests/cases/compiler/namespaceDisambiguationInUnion.ts(13,7): error TS2739: Type '{ type: string; }[]' is missing the following properties from type '[Foo.Yep, Bar.Yep]': 0, 1 +tests/cases/compiler/namespaceDisambiguationInUnion.ts(13,7): error TS2322: Type '{ type: string; }[]' is not assignable to type '[Foo.Yep, Bar.Yep]'. + Target requires 2 element(s) but source may have fewer. ==== tests/cases/compiler/namespaceDisambiguationInUnion.ts (2 errors) ==== @@ -25,5 +26,6 @@ tests/cases/compiler/namespaceDisambiguationInUnion.ts(13,7): error TS2739: Type const y = [{ type: "a" }, { type: "b" }]; const val2: [Foo.Yep, Bar.Yep] = y; ~~~~ -!!! error TS2739: Type '{ type: string; }[]' is missing the following properties from type '[Foo.Yep, Bar.Yep]': 0, 1 +!!! error TS2322: Type '{ type: string; }[]' is not assignable to type '[Foo.Yep, Bar.Yep]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. \ No newline at end of file diff --git a/tests/baselines/reference/nonIterableRestElement1.types b/tests/baselines/reference/nonIterableRestElement1.types index c226eb0413854..5e39f1e101c0d 100644 --- a/tests/baselines/reference/nonIterableRestElement1.types +++ b/tests/baselines/reference/nonIterableRestElement1.types @@ -5,7 +5,7 @@ var c = {}; [...c] = ["", 0]; >[...c] = ["", 0] : (string | number)[] ->[...c] : undefined[] +>[...c] : unknown[] >...c : any >c : {} >["", 0] : (string | number)[] diff --git a/tests/baselines/reference/nonIterableRestElement2.types b/tests/baselines/reference/nonIterableRestElement2.types index af99cc046558c..625006eff1682 100644 --- a/tests/baselines/reference/nonIterableRestElement2.types +++ b/tests/baselines/reference/nonIterableRestElement2.types @@ -5,7 +5,7 @@ var c = {}; [...c] = ["", 0]; >[...c] = ["", 0] : (string | number)[] ->[...c] : undefined[] +>[...c] : unknown[] >...c : any >c : {} >["", 0] : (string | number)[] diff --git a/tests/baselines/reference/nonIterableRestElement3.types b/tests/baselines/reference/nonIterableRestElement3.types index ee79c1d0e6719..0b44960a96e7e 100644 --- a/tests/baselines/reference/nonIterableRestElement3.types +++ b/tests/baselines/reference/nonIterableRestElement3.types @@ -7,7 +7,7 @@ var c = { bogus: 0 }; [...c] = ["", 0]; >[...c] = ["", 0] : (string | number)[] ->[...c] : undefined[] +>[...c] : unknown[] >...c : any >c : { bogus: number; } >["", 0] : (string | number)[] diff --git a/tests/baselines/reference/optionalTupleElements1.errors.txt b/tests/baselines/reference/optionalTupleElements1.errors.txt index bb5fd2c01d8cb..148c66977429e 100644 --- a/tests/baselines/reference/optionalTupleElements1.errors.txt +++ b/tests/baselines/reference/optionalTupleElements1.errors.txt @@ -1,28 +1,16 @@ tests/cases/conformance/types/tuple/optionalTupleElements1.ts(11,29): error TS1257: A required element cannot follow an optional element. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(15,5): error TS2322: Type 'T2' is not assignable to type 'T1'. - Types of property '2' are incompatible. - Type 'boolean | undefined' is not assignable to type 'boolean'. - Type 'undefined' is not assignable to type 'boolean'. + Property '2' is optional in type '[number, string, (boolean | undefined)?]' but required in type '[number, string, boolean]'. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(16,5): error TS2322: Type 'T3' is not assignable to type 'T1'. - Types of property '1' are incompatible. - Type 'string | undefined' is not assignable to type 'string'. - Type 'undefined' is not assignable to type 'string'. + Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(17,5): error TS2322: Type 'T4' is not assignable to type 'T1'. - Types of property '0' are incompatible. - Type 'number | undefined' is not assignable to type 'number'. - Type 'undefined' is not assignable to type 'number'. + Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(20,5): error TS2322: Type 'T3' is not assignable to type 'T2'. - Types of property '1' are incompatible. - Type 'string | undefined' is not assignable to type 'string'. - Type 'undefined' is not assignable to type 'string'. + Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(21,5): error TS2322: Type 'T4' is not assignable to type 'T2'. - Types of property '0' are incompatible. - Type 'number | undefined' is not assignable to type 'number'. - Type 'undefined' is not assignable to type 'number'. + Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(25,5): error TS2322: Type 'T4' is not assignable to type 'T3'. - Types of property '0' are incompatible. - Type 'number | undefined' is not assignable to type 'number'. - Type 'undefined' is not assignable to type 'number'. + Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, (string | undefined)?, (boolean | undefined)?]'. ==== tests/cases/conformance/types/tuple/optionalTupleElements1.ts (7 errors) ==== @@ -45,44 +33,32 @@ tests/cases/conformance/types/tuple/optionalTupleElements1.ts(25,5): error TS232 t1 = t2; // Error ~~ !!! error TS2322: Type 'T2' is not assignable to type 'T1'. -!!! error TS2322: Types of property '2' are incompatible. -!!! error TS2322: Type 'boolean | undefined' is not assignable to type 'boolean'. -!!! error TS2322: Type 'undefined' is not assignable to type 'boolean'. +!!! error TS2322: Property '2' is optional in type '[number, string, (boolean | undefined)?]' but required in type '[number, string, boolean]'. t1 = t3; // Error ~~ !!! error TS2322: Type 'T3' is not assignable to type 'T1'. -!!! error TS2322: Types of property '1' are incompatible. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! error TS2322: Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. t1 = t4; // Error ~~ !!! error TS2322: Type 'T4' is not assignable to type 'T1'. -!!! error TS2322: Types of property '0' are incompatible. -!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'. -!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! error TS2322: Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. t2 = t1; t2 = t2; t2 = t3; // Error ~~ !!! error TS2322: Type 'T3' is not assignable to type 'T2'. -!!! error TS2322: Types of property '1' are incompatible. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! error TS2322: Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. t2 = t4; // Error ~~ !!! error TS2322: Type 'T4' is not assignable to type 'T2'. -!!! error TS2322: Types of property '0' are incompatible. -!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'. -!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! error TS2322: Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. t3 = t1; t3 = t2; t3 = t3; t3 = t4; // Error ~~ !!! error TS2322: Type 'T4' is not assignable to type 'T3'. -!!! error TS2322: Types of property '0' are incompatible. -!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'. -!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! error TS2322: Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, (string | undefined)?, (boolean | undefined)?]'. t4 = t1; t4 = t2; t4 = t3; diff --git a/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt b/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt index 77e78a676b406..3c870250df7f9 100644 --- a/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt +++ b/tests/baselines/reference/promiseEmptyTupleNoException.errors.txt @@ -1,6 +1,5 @@ tests/cases/compiler/promiseEmptyTupleNoException.ts(3,3): error TS2322: Type 'any[]' is not assignable to type '[]'. - Types of property 'length' are incompatible. - Type 'number' is not assignable to type '0'. + Target allows only 0 element(s) but source may have more. ==== tests/cases/compiler/promiseEmptyTupleNoException.ts (1 errors) ==== @@ -9,7 +8,6 @@ tests/cases/compiler/promiseEmptyTupleNoException.ts(3,3): error TS2322: Type 'a return emails; ~~~~~~~~~~~~~~ !!! error TS2322: Type 'any[]' is not assignable to type '[]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type 'number' is not assignable to type '0'. +!!! error TS2322: Target allows only 0 element(s) but source may have more. } \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccessChain.3.types b/tests/baselines/reference/propertyAccessChain.3.types index a5b97624e2475..ef31d61de9070 100644 --- a/tests/baselines/reference/propertyAccessChain.3.types +++ b/tests/baselines/reference/propertyAccessChain.3.types @@ -170,7 +170,7 @@ for (obj?.a.b of []); [...obj?.a] = []; >[...obj?.a] = [] : never[] ->[...obj?.a] : never[] +>[...obj?.a] : any[] >...obj?.a : any >obj?.a : any >obj : any @@ -179,7 +179,7 @@ for (obj?.a.b of []); [...obj?.a.b] = []; >[...obj?.a.b] = [] : never[] ->[...obj?.a.b] : never[] +>[...obj?.a.b] : any[] >...obj?.a.b : any >obj?.a.b : any >obj?.a : any diff --git a/tests/baselines/reference/ramdaToolsNoInfinite.types b/tests/baselines/reference/ramdaToolsNoInfinite.types index 6f5088165e89e..a4741e1f74e6f 100644 --- a/tests/baselines/reference/ramdaToolsNoInfinite.types +++ b/tests/baselines/reference/ramdaToolsNoInfinite.types @@ -54,7 +54,7 @@ declare namespace Tools { T['length']; type Prepend = ->Prepend : Prepend +>Prepend : [head: E, ...args: T] ((head: E, ...args: T) => any) extends ((...args: infer U) => any) >head : E @@ -68,7 +68,7 @@ declare namespace Tools { >Drop : Drop 0: Drop, Prepend>; ->0 : Drop, Prepend> +>0 : Drop, [head: any, ...args: I]> 1: T; >1 : T @@ -88,7 +88,7 @@ declare namespace Tools { Length; type Next = ->Next : Prepend +>Next : [head: any, ...args: I] Prepend; @@ -101,7 +101,7 @@ declare namespace Tools { >Iterator : Iterator 0: Iterator, Next>; ->0 : Iterator, Prepend> +>0 : Iterator 1: From; >1 : From @@ -116,7 +116,7 @@ declare namespace Tools { >Reverse : Reverse 0: Reverse], R>, Next>; ->0 : Reverse], R>, Prepend> +>0 : Reverse], ...args: R], [head: any, ...args: I]> 1: R; >1 : R @@ -163,7 +163,7 @@ declare namespace Curry { interface GapsOfWorker { 0: GapsOf extends infer G ? Tools.Cast : never, Tools.Next>; ->0 : GapsOf extends infer G ? Tools.Cast : never, Tools.Prepend> +>0 : GapsOf extends infer G ? Tools.Cast : never, [head: any, ...args: I]> >Tools : any >Tools : any diff --git a/tests/baselines/reference/readonlyArraysAndTuples.errors.txt b/tests/baselines/reference/readonlyArraysAndTuples.errors.txt index 8a18ff29a97f4..76930007d252e 100644 --- a/tests/baselines/reference/readonlyArraysAndTuples.errors.txt +++ b/tests/baselines/reference/readonlyArraysAndTuples.errors.txt @@ -4,11 +4,14 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(11,12): error TS1 tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(12,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(15,5): error TS4104: The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(17,5): error TS4104: The type 'readonly [string, string]' is 'readonly' and cannot be assigned to the mutable type 'string[]'. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(21,5): error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1 +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(21,5): error TS2322: Type 'string[]' is not assignable to type '[string, string]'. + Target requires 2 element(s) but source may have fewer. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS4104: The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type '[string, string]'. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS4104: The type 'readonly [string, string]' is 'readonly' and cannot be assigned to the mutable type '[string, string]'. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2322: Type 'string[]' is not assignable to type 'readonly [string, string]'. + Target requires 2 element(s) but source may have fewer. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS2322: Type 'readonly string[]' is not assignable to type 'readonly [string, string]'. + Target requires 2 element(s) but source may have fewer. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(30,3): error TS2540: Cannot assign to '0' because it is a read-only property. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(31,3): error TS2540: Cannot assign to '1' because it is a read-only property. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(32,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading. @@ -53,7 +56,8 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(36,8): error TS25 ra = rt; mt = ma; // Error ~~ -!!! error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1 +!!! error TS2322: Type 'string[]' is not assignable to type '[string, string]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. mt = ra; // Error ~~ !!! error TS4104: The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type '[string, string]'. @@ -62,10 +66,12 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(36,8): error TS25 !!! error TS4104: The type 'readonly [string, string]' is 'readonly' and cannot be assigned to the mutable type '[string, string]'. rt = ma; // Error ~~ -!!! error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 +!!! error TS2322: Type 'string[]' is not assignable to type 'readonly [string, string]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. rt = ra; // Error ~~ -!!! error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 +!!! error TS2322: Type 'readonly string[]' is not assignable to type 'readonly [string, string]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. rt = mt; } diff --git a/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt b/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt index 3f328deb405d2..833b39cf7e032 100644 --- a/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt +++ b/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt @@ -11,15 +11,12 @@ tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(23,9): error TS2345: Ar tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(24,9): error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. The type 'readonly number[]' is 'readonly' and cannot be assigned to the mutable type 'number[]'. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(27,7): error TS2322: Type 'readonly [1]' is not assignable to type 'readonly []'. - Types of property 'length' are incompatible. - Type '1' is not assignable to type '0'. + Source has 1 element(s) but target allows only 0. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(30,7): error TS4104: The type 'readonly [1]' is 'readonly' and cannot be assigned to the mutable type '[]'. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(33,7): error TS2322: Type '[1]' is not assignable to type 'readonly []'. - Types of property 'length' are incompatible. - Type '1' is not assignable to type '0'. + Source has 1 element(s) but target allows only 0. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(36,7): error TS2322: Type '[1]' is not assignable to type '[]'. - Types of property 'length' are incompatible. - Type '1' is not assignable to type '0'. + Source has 1 element(s) but target allows only 0. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(39,7): error TS2322: Type 'readonly number[]' is not assignable to type 'readonly boolean[]'. Type 'number' is not assignable to type 'boolean'. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(42,7): error TS4104: The type 'readonly number[]' is 'readonly' and cannot be assigned to the mutable type 'boolean[]'. @@ -34,10 +31,13 @@ tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(57,7): error TS2322: Ty Type '1' is not assignable to type 'boolean'. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(60,7): error TS2322: Type '[1]' is not assignable to type 'boolean[]'. Type '1' is not assignable to type 'boolean'. -tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(63,7): error TS2741: Property '0' is missing in type 'readonly number[]' but required in type 'readonly [1]'. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(63,7): error TS2322: Type 'readonly number[]' is not assignable to type 'readonly [1]'. + Target requires 1 element(s) but source may have fewer. tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(66,7): error TS4104: The type 'readonly number[]' is 'readonly' and cannot be assigned to the mutable type '[1]'. -tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(69,7): error TS2741: Property '0' is missing in type 'number[]' but required in type 'readonly [1]'. -tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(72,7): error TS2741: Property '0' is missing in type 'number[]' but required in type '[1]'. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(69,7): error TS2322: Type 'number[]' is not assignable to type 'readonly [1]'. + Target requires 1 element(s) but source may have fewer. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(72,7): error TS2322: Type 'number[]' is not assignable to type '[1]'. + Target requires 1 element(s) but source may have fewer. ==== tests/cases/compiler/readonlyTupleAndArrayElaboration.ts (22 errors) ==== @@ -88,8 +88,7 @@ tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(72,7): error TS2741: Pr const t2: readonly [] = t1; ~~ !!! error TS2322: Type 'readonly [1]' is not assignable to type 'readonly []'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '1' is not assignable to type '0'. +!!! error TS2322: Source has 1 element(s) but target allows only 0. const t3: readonly [1] = [1]; const t4: [] = t3; @@ -100,15 +99,13 @@ tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(72,7): error TS2741: Pr const t6: readonly [] = t5; ~~ !!! error TS2322: Type '[1]' is not assignable to type 'readonly []'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '1' is not assignable to type '0'. +!!! error TS2322: Source has 1 element(s) but target allows only 0. const t7: [1] = [1]; const t8: [] = t7; ~~ !!! error TS2322: Type '[1]' is not assignable to type '[]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '1' is not assignable to type '0'. +!!! error TS2322: Source has 1 element(s) but target allows only 0. const a1: readonly number[] = [1]; const a2: readonly boolean[] = a1; @@ -159,7 +156,8 @@ tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(72,7): error TS2741: Pr const at1: readonly number[] = [1]; const at2: readonly [1] = at1; ~~~ -!!! error TS2741: Property '0' is missing in type 'readonly number[]' but required in type 'readonly [1]'. +!!! error TS2322: Type 'readonly number[]' is not assignable to type 'readonly [1]'. +!!! error TS2322: Target requires 1 element(s) but source may have fewer. const at3: readonly number[] = [1]; const at4: [1] = at3; @@ -169,10 +167,12 @@ tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(72,7): error TS2741: Pr const at5: number[] = [1]; const at6: readonly [1] = at5; ~~~ -!!! error TS2741: Property '0' is missing in type 'number[]' but required in type 'readonly [1]'. +!!! error TS2322: Type 'number[]' is not assignable to type 'readonly [1]'. +!!! error TS2322: Target requires 1 element(s) but source may have fewer. const at7: number[] = [1]; const at8: [1] = at7; ~~~ -!!! error TS2741: Property '0' is missing in type 'number[]' but required in type '[1]'. +!!! error TS2322: Type 'number[]' is not assignable to type '[1]'. +!!! error TS2322: Target requires 1 element(s) but source may have fewer. \ No newline at end of file diff --git a/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt b/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt index ad5fe6dc1aedc..c72f99027abfb 100644 --- a/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt +++ b/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt @@ -1,10 +1,9 @@ tests/cases/compiler/recursiveResolveTypeMembers.ts(4,49): error TS2577: Return type annotation circularly references itself. tests/cases/compiler/recursiveResolveTypeMembers.ts(4,58): error TS2304: Cannot find name 'H'. -tests/cases/compiler/recursiveResolveTypeMembers.ts(4,62): error TS2574: A rest element type must be an array type. tests/cases/compiler/recursiveResolveTypeMembers.ts(4,79): error TS2304: Cannot find name 'R'. -==== tests/cases/compiler/recursiveResolveTypeMembers.ts (4 errors) ==== +==== tests/cases/compiler/recursiveResolveTypeMembers.ts (3 errors) ==== // Repro from #25291 type PromisedTuple void> = @@ -13,8 +12,6 @@ tests/cases/compiler/recursiveResolveTypeMembers.ts(4,79): error TS2304: Cannot !!! error TS2577: Return type annotation circularly references itself. ~ !!! error TS2304: Cannot find name 'H'. - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2574: A rest element type must be an array type. ~ !!! error TS2304: Cannot find name 'R'. diff --git a/tests/baselines/reference/restElementWithAssignmentPattern2.types b/tests/baselines/reference/restElementWithAssignmentPattern2.types index 4f6366dff7fd8..ae41646624eb4 100644 --- a/tests/baselines/reference/restElementWithAssignmentPattern2.types +++ b/tests/baselines/reference/restElementWithAssignmentPattern2.types @@ -5,7 +5,7 @@ var a: string, b: number; [...{ 0: a = "", b }] = ["", 1]; >[...{ 0: a = "", b }] = ["", 1] : (string | number)[] ->[...{ 0: a = "", b }] : undefined[] +>[...{ 0: a = "", b }] : unknown[] >...{ 0: a = "", b } : any >{ 0: a = "", b } : { 0?: string; b: number; } >0 : string diff --git a/tests/baselines/reference/restElementWithAssignmentPattern4.types b/tests/baselines/reference/restElementWithAssignmentPattern4.types index 688735982ccb5..295897d481ded 100644 --- a/tests/baselines/reference/restElementWithAssignmentPattern4.types +++ b/tests/baselines/reference/restElementWithAssignmentPattern4.types @@ -11,7 +11,7 @@ var tuple: [string, number] = ["", 1]; [...{ 0: a = "", b }] = tuple; >[...{ 0: a = "", b }] = tuple : [string, number] ->[...{ 0: a = "", b }] : undefined[] +>[...{ 0: a = "", b }] : unknown[] >...{ 0: a = "", b } : any >{ 0: a = "", b } : { 0?: string; b: number; } >0 : string diff --git a/tests/baselines/reference/restTupleElements1.errors.txt b/tests/baselines/reference/restTupleElements1.errors.txt index 316ecc209aa73..304046672a189 100644 --- a/tests/baselines/reference/restTupleElements1.errors.txt +++ b/tests/baselines/reference/restTupleElements1.errors.txt @@ -4,26 +4,25 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(9,13): error TS2574: A tests/cases/conformance/types/tuple/restTupleElements1.ts(10,13): error TS2574: A rest element type must be an array type. tests/cases/conformance/types/tuple/restTupleElements1.ts(10,16): error TS8020: JSDoc types can only be used inside documentation comments. tests/cases/conformance/types/tuple/restTupleElements1.ts(23,31): error TS2344: Type 'number[]' does not satisfy the constraint '[number, ...number[]]'. - Property '0' is missing in type 'number[]' but required in type '[number, ...number[]]'. + Property '0' is optional in type 'number[]' but required in type '[number, ...number[]]'. tests/cases/conformance/types/tuple/restTupleElements1.ts(24,31): error TS2344: Type '[]' does not satisfy the constraint '[number, ...number[]]'. - Property '0' is missing in type '[]' but required in type '[number, ...number[]]'. + Source has 0 element(s) but target requires 1. tests/cases/conformance/types/tuple/restTupleElements1.ts(29,18): error TS2344: Type 'number[]' does not satisfy the constraint '[number]'. - Property '0' is missing in type 'number[]' but required in type '[number]'. + Target requires 1 element(s) but source may have fewer. tests/cases/conformance/types/tuple/restTupleElements1.ts(30,18): error TS2344: Type '[number, ...number[]]' does not satisfy the constraint '[number]'. - Types of property 'length' are incompatible. - Type 'number' is not assignable to type '1'. + Target allows only 1 element(s) but source may have more. tests/cases/conformance/types/tuple/restTupleElements1.ts(32,31): error TS2344: Type '[number, ...string[]]' does not satisfy the constraint '[number, ...number[]]'. Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(33,31): error TS2344: Type '[string, ...number[]]' does not satisfy the constraint '[number, ...number[]]'. Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(34,31): error TS2344: Type '[number, number, string]' does not satisfy the constraint '[number, ...number[]]'. - Property '2' is incompatible with rest element type. + Types of property '2' are incompatible. Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(35,31): error TS2344: Type '[number, number, number, string]' does not satisfy the constraint '[number, ...number[]]'. - Property '3' is incompatible with rest element type. + Types of property '3' are incompatible. Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[]]'. - Property '0' is missing in type '[]' but required in type '[unknown, ...unknown[]]'. + Source has 0 element(s) but target requires 1. ==== tests/cases/conformance/types/tuple/restTupleElements1.ts (14 errors) ==== @@ -62,11 +61,11 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A assign<[number, ...number[]], number[]>(); // Error ~~~~~~~~ !!! error TS2344: Type 'number[]' does not satisfy the constraint '[number, ...number[]]'. -!!! error TS2344: Property '0' is missing in type 'number[]' but required in type '[number, ...number[]]'. +!!! error TS2344: Property '0' is optional in type 'number[]' but required in type '[number, ...number[]]'. assign<[number, ...number[]], []>(); // Error ~~ !!! error TS2344: Type '[]' does not satisfy the constraint '[number, ...number[]]'. -!!! error TS2344: Property '0' is missing in type '[]' but required in type '[number, ...number[]]'. +!!! error TS2344: Source has 0 element(s) but target requires 1. assign<[number, ...number[]], [number]>(); assign<[number, ...number[]], [number, number]>(); assign<[number, ...number[]], [number, number, ...number[]]>(); @@ -74,12 +73,11 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A assign<[number], [...number[]]>(); // Error ~~~~~~~~~~~~~ !!! error TS2344: Type 'number[]' does not satisfy the constraint '[number]'. -!!! error TS2344: Property '0' is missing in type 'number[]' but required in type '[number]'. +!!! error TS2344: Target requires 1 element(s) but source may have fewer. assign<[number], [number, ...number[]]>(); // Error ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, ...number[]]' does not satisfy the constraint '[number]'. -!!! error TS2344: Types of property 'length' are incompatible. -!!! error TS2344: Type 'number' is not assignable to type '1'. +!!! error TS2344: Target allows only 1 element(s) but source may have more. assign<[number, ...number[]], [number, ...string[]]>(); // Error ~~~~~~~~~~~~~~~~~~~~~ @@ -92,12 +90,12 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A assign<[number, ...number[]], [number, number, string]>(); // Error ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, number, string]' does not satisfy the constraint '[number, ...number[]]'. -!!! error TS2344: Property '2' is incompatible with rest element type. +!!! error TS2344: Types of property '2' are incompatible. !!! error TS2344: Type 'string' is not assignable to type 'number'. assign<[number, ...number[]], [number, number, number, string]>(); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, number, number, string]' does not satisfy the constraint '[number, ...number[]]'. -!!! error TS2344: Property '3' is incompatible with rest element type. +!!! error TS2344: Types of property '3' are incompatible. !!! error TS2344: Type 'string' is not assignable to type 'number'. type T20 = [number, string, ...boolean[]]; @@ -125,7 +123,7 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A f0([]); // Error ~~ !!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[]]'. -!!! error TS2345: Property '0' is missing in type '[]' but required in type '[unknown, ...unknown[]]'. +!!! error TS2345: Source has 0 element(s) but target requires 1. f0([1]); f0([1, 2, 3]); f0([1, "hello", true]); diff --git a/tests/baselines/reference/restTupleElements1.types b/tests/baselines/reference/restTupleElements1.types index 48d0014a54879..a910315c51d82 100644 --- a/tests/baselines/reference/restTupleElements1.types +++ b/tests/baselines/reference/restTupleElements1.types @@ -24,10 +24,10 @@ type T07 = [...string[], string]; // Error >T07 : T07 type T08 = [...string]; // Error ->T08 : T08 +>T08 : any[] type T09 = [...string?]; // Error ->T09 : T09 +>T09 : any[] type T10 = [string, ...[...string[]]]; >T10 : T10 @@ -107,7 +107,7 @@ type T21 = T20[0]; >T21 : number type T22 = T20[0 | 1]; ->T22 : string | number +>T22 : T22 type T23 = T20[0 | 1 | 2]; >T23 : string | number | boolean diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt index 5c3d13b87e468..31b1845e2f458 100644 --- a/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt +++ b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt @@ -1,7 +1,8 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error TS2345: Argument of type '(a: number, b: T[0], ...x: T[number][]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'. Types of parameters 'b' and 'args' are incompatible. Type 'T' is not assignable to type '[b: T[0], ...x: T[number][]]'. - Property '0' is missing in type 'any[]' but required in type '[b: T[0], ...x: T[number][]]'. + Type 'any[]' is not assignable to type '[b: T[0], ...x: T[number][]]'. + Property '0' is optional in type 'any[]' but required in type '[b: T[0], ...x: T[number][]]'. ==== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts (1 errors) ==== @@ -65,7 +66,8 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error !!! error TS2345: Argument of type '(a: number, b: T[0], ...x: T[number][]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'. !!! error TS2345: Types of parameters 'b' and 'args' are incompatible. !!! error TS2345: Type 'T' is not assignable to type '[b: T[0], ...x: T[number][]]'. -!!! error TS2345: Property '0' is missing in type 'any[]' but required in type '[b: T[0], ...x: T[number][]]'. +!!! error TS2345: Type 'any[]' is not assignable to type '[b: T[0], ...x: T[number][]]'. +!!! error TS2345: Property '0' is optional in type 'any[]' but required in type '[b: T[0], ...x: T[number][]]'. } declare function f5(f: (...args: T) => U): (...args: T) => U; diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.types b/tests/baselines/reference/restTuplesFromContextualTypes.types index b43299fc6dd5b..b62045eba3166 100644 --- a/tests/baselines/reference/restTuplesFromContextualTypes.types +++ b/tests/baselines/reference/restTuplesFromContextualTypes.types @@ -314,10 +314,10 @@ function f4(t: T) { (function(a, ...x){})(1, 2, ...t); >(function(a, ...x){})(1, 2, ...t) : void ->(function(a, ...x){}) : (a: number, x_0: number, ...x_1: any[]) => void ->function(a, ...x){} : (a: number, x_0: number, ...x_1: any[]) => void +>(function(a, ...x){}) : (a: number, x_0: number, ...x_1: T) => void +>function(a, ...x){} : (a: number, x_0: number, ...x_1: T) => void >a : number ->x : [number, ...any[]] +>x : [number, ...T] >1 : 1 >2 : 2 >...t : any @@ -332,8 +332,8 @@ function f4(t: T) { f((...x) => {}); >f((...x) => {}) : void >f : (cb: (x: number, ...args: T) => void) => void ->(...x) => {} : (x: number, ...args: T[number][]) => void ->x : [x: number, ...args: T[number][]] +>(...x) => {} : (x: number, ...args: T) => void +>x : [x: number, ...args: T] f((a, ...x) => {}); >f((a, ...x) => {}) : void diff --git a/tests/baselines/reference/restTypeRetainsMappyness.errors.txt b/tests/baselines/reference/restTypeRetainsMappyness.errors.txt deleted file mode 100644 index 26cc5db846d5e..0000000000000 --- a/tests/baselines/reference/restTypeRetainsMappyness.errors.txt +++ /dev/null @@ -1,15 +0,0 @@ -tests/cases/compiler/restTypeRetainsMappyness.ts(7,8): error TS2345: Argument of type 'Foo[number][]' is not assignable to parameter of type 'Foo'. - - -==== tests/cases/compiler/restTypeRetainsMappyness.ts (1 errors) ==== - type Foo = { - [P in keyof T]: T[P] - } - - function test(fn: (...args: Foo) => void) { - const arr: Foo = {} as any - fn(...arr) // Error: Argument of type 'any[]' is not assignable to parameter of type 'Foo' - ~~~~~~ -!!! error TS2345: Argument of type 'Foo[number][]' is not assignable to parameter of type 'Foo'. - } - \ No newline at end of file diff --git a/tests/baselines/reference/spliceTuples.errors.txt b/tests/baselines/reference/spliceTuples.errors.txt index 879f0659b3f94..7346c7b1f820e 100644 --- a/tests/baselines/reference/spliceTuples.errors.txt +++ b/tests/baselines/reference/spliceTuples.errors.txt @@ -1,4 +1,5 @@ -tests/cases/compiler/spliceTuples.ts(23,1): error TS2741: Property '3' is missing in type '[number, string, boolean, ...boolean[]]' but required in type '[number, string, boolean, boolean, ...boolean[]]'. +tests/cases/compiler/spliceTuples.ts(23,1): error TS2322: Type '[number, string, boolean, ...boolean[]]' is not assignable to type '[number, string, boolean, boolean, ...boolean[]]'. + Property '3' is optional in type '[number, string, boolean, ...boolean[]]' but required in type '[number, string, boolean, boolean, ...boolean[]]'. ==== tests/cases/compiler/spliceTuples.ts (1 errors) ==== @@ -26,5 +27,6 @@ tests/cases/compiler/spliceTuples.ts(23,1): error TS2741: Property '3' is missin let k6: [number, string, boolean, boolean, ...boolean[]]; k6 = [1, ...sbb_]; ~~ -!!! error TS2741: Property '3' is missing in type '[number, string, boolean, ...boolean[]]' but required in type '[number, string, boolean, boolean, ...boolean[]]'. +!!! error TS2322: Type '[number, string, boolean, ...boolean[]]' is not assignable to type '[number, string, boolean, boolean, ...boolean[]]'. +!!! error TS2322: Property '3' is optional in type '[number, string, boolean, ...boolean[]]' but required in type '[number, string, boolean, boolean, ...boolean[]]'. \ No newline at end of file diff --git a/tests/baselines/reference/strictBindCallApply1.errors.txt b/tests/baselines/reference/strictBindCallApply1.errors.txt index 1747e6910eb6f..c9e62c74f0c47 100644 --- a/tests/baselines/reference/strictBindCallApply1.errors.txt +++ b/tests/baselines/reference/strictBindCallApply1.errors.txt @@ -10,11 +10,10 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(17,15): error TS2554: tests/cases/conformance/functions/strictBindCallApply1.ts(18,35): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/functions/strictBindCallApply1.ts(19,44): error TS2554: Expected 3 arguments, but got 4. tests/cases/conformance/functions/strictBindCallApply1.ts(22,32): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[a: number, b: string]'. - Property '1' is missing in type '[number]' but required in type '[a: number, b: string]'. + Source has 1 element(s) but target requires 2. tests/cases/conformance/functions/strictBindCallApply1.ts(23,37): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/functions/strictBindCallApply1.ts(24,32): error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/conformance/functions/strictBindCallApply1.ts(41,11): error TS2769: No overload matches this call. Overload 1 of 6, '(this: (this: C, arg0: 10, arg1: string) => string, thisArg: C, arg0: 10, arg1: string): () => string', gave the following error. Argument of type 'number' is not assignable to parameter of type 'string'. @@ -36,11 +35,10 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(49,29): error TS2345: tests/cases/conformance/functions/strictBindCallApply1.ts(50,38): error TS2554: Expected 3 arguments, but got 4. tests/cases/conformance/functions/strictBindCallApply1.ts(51,22): error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'C'. tests/cases/conformance/functions/strictBindCallApply1.ts(54,26): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[a: number, b: string]'. - Property '1' is missing in type '[number]' but required in type '[a: number, b: string]'. + Source has 1 element(s) but target requires 2. tests/cases/conformance/functions/strictBindCallApply1.ts(55,31): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/functions/strictBindCallApply1.ts(56,26): error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/conformance/functions/strictBindCallApply1.ts(57,23): error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'C'. tests/cases/conformance/functions/strictBindCallApply1.ts(62,11): error TS2769: No overload matches this call. Overload 1 of 6, '(this: new (arg0: 10, arg1: string) => C, thisArg: any, arg0: 10, arg1: string): new () => C', gave the following error. @@ -54,11 +52,10 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(65,3): error TS2554: E tests/cases/conformance/functions/strictBindCallApply1.ts(66,15): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/functions/strictBindCallApply1.ts(67,24): error TS2554: Expected 3 arguments, but got 4. tests/cases/conformance/functions/strictBindCallApply1.ts(70,12): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[a: number, b: string]'. - Property '1' is missing in type '[number]' but required in type '[a: number, b: string]'. + Source has 1 element(s) but target requires 2. tests/cases/conformance/functions/strictBindCallApply1.ts(71,17): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/functions/strictBindCallApply1.ts(72,12): error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. ==== tests/cases/conformance/functions/strictBindCallApply1.ts (24 errors) ==== @@ -101,15 +98,14 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(72,12): error TS2345: let a01 = foo.apply(undefined, [10]); // Error ~~~~ !!! error TS2345: Argument of type '[number]' is not assignable to parameter of type '[a: number, b: string]'. -!!! error TS2345: Property '1' is missing in type '[number]' but required in type '[a: number, b: string]'. +!!! error TS2345: Source has 1 element(s) but target requires 2. let a02 = foo.apply(undefined, [10, 20]); // Error ~~ !!! error TS2322: Type 'number' is not assignable to type 'string'. let a03 = foo.apply(undefined, [10, "hello", 30]); // Error ~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '3' is not assignable to type '2'. +!!! error TS2345: Source has 3 element(s) but target allows only 2. class C { constructor(a: number, b: string) {} @@ -168,15 +164,14 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(72,12): error TS2345: let a11 = c.foo.apply(c, [10]); // Error ~~~~ !!! error TS2345: Argument of type '[number]' is not assignable to parameter of type '[a: number, b: string]'. -!!! error TS2345: Property '1' is missing in type '[number]' but required in type '[a: number, b: string]'. +!!! error TS2345: Source has 1 element(s) but target requires 2. let a12 = c.foo.apply(c, [10, 20]); // Error ~~ !!! error TS2322: Type 'number' is not assignable to type 'string'. let a13 = c.foo.apply(c, [10, "hello", 30]); // Error ~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '3' is not assignable to type '2'. +!!! error TS2345: Source has 3 element(s) but target allows only 2. let a14 = c.foo.apply(undefined, [10, "hello"]); // Error ~~~~~~~~~ !!! error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'C'. @@ -210,13 +205,12 @@ tests/cases/conformance/functions/strictBindCallApply1.ts(72,12): error TS2345: C.apply(c, [10]); // Error ~~~~ !!! error TS2345: Argument of type '[number]' is not assignable to parameter of type '[a: number, b: string]'. -!!! error TS2345: Property '1' is missing in type '[number]' but required in type '[a: number, b: string]'. +!!! error TS2345: Source has 1 element(s) but target requires 2. C.apply(c, [10, 20]); // Error ~~ !!! error TS2322: Type 'number' is not assignable to type 'string'. C.apply(c, [10, "hello", 30]); // Error ~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '[number, string, number]' is not assignable to parameter of type '[a: number, b: string]'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '3' is not assignable to type '2'. +!!! error TS2345: Source has 3 element(s) but target allows only 2. \ No newline at end of file diff --git a/tests/baselines/reference/strictTupleLength.errors.txt b/tests/baselines/reference/strictTupleLength.errors.txt index 78cf7b47e97ae..4adc4d1ab4c99 100644 --- a/tests/baselines/reference/strictTupleLength.errors.txt +++ b/tests/baselines/reference/strictTupleLength.errors.txt @@ -1,6 +1,7 @@ tests/cases/conformance/types/tuple/strictTupleLength.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't1' must be of type '[number]', but here has type '[number, number]'. tests/cases/conformance/types/tuple/strictTupleLength.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type '[number, number]', but here has type '[number]'. -tests/cases/conformance/types/tuple/strictTupleLength.ts(18,1): error TS2741: Property '0' is missing in type 'number[]' but required in type '[number]'. +tests/cases/conformance/types/tuple/strictTupleLength.ts(18,1): error TS2322: Type 'number[]' is not assignable to type '[number]'. + Target requires 1 element(s) but source may have fewer. ==== tests/cases/conformance/types/tuple/strictTupleLength.ts (3 errors) ==== @@ -29,6 +30,7 @@ tests/cases/conformance/types/tuple/strictTupleLength.ts(18,1): error TS2741: Pr t1 = arr; // error with or without strict ~~ -!!! error TS2741: Property '0' is missing in type 'number[]' but required in type '[number]'. +!!! error TS2322: Type 'number[]' is not assignable to type '[number]'. +!!! error TS2322: Target requires 1 element(s) but source may have fewer. arr = t1; // ok with or without strict \ No newline at end of file diff --git a/tests/baselines/reference/trailingCommasInBindingPatterns.types b/tests/baselines/reference/trailingCommasInBindingPatterns.types index 087bb0c0b31ee..04754797495cd 100644 --- a/tests/baselines/reference/trailingCommasInBindingPatterns.types +++ b/tests/baselines/reference/trailingCommasInBindingPatterns.types @@ -14,7 +14,7 @@ let c, d; ([...c,] = []); >([...c,] = []) : undefined[] >[...c,] = [] : undefined[] ->[...c,] : undefined[] +>[...c,] : any[] >...c : any >c : any >[] : undefined[] diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index af76c872a6f38..df0752ebee37f 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -1,12 +1,13 @@ tests/cases/compiler/tupleTypes.ts(11,12): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. tests/cases/compiler/tupleTypes.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type 'undefined', but here has type 'string | number'. -tests/cases/compiler/tupleTypes.ts(14,1): error TS2739: Type '[]' is missing the following properties from type '[number, string]': 0, 1 -tests/cases/compiler/tupleTypes.ts(15,1): error TS2741: Property '1' is missing in type '[number]' but required in type '[number, string]'. +tests/cases/compiler/tupleTypes.ts(14,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. + Source has 0 element(s) but target requires 2. +tests/cases/compiler/tupleTypes.ts(15,1): error TS2322: Type '[number]' is not assignable to type '[number, string]'. + Source has 1 element(s) but target requires 2. tests/cases/compiler/tupleTypes.ts(17,6): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(17,15): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. tests/cases/compiler/tupleTypes.ts(35,14): error TS2493: Tuple type '[number, string]' of length '2' has no element at index '2'. tests/cases/compiler/tupleTypes.ts(36,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'tt2' must be of type 'undefined', but here has type 'string | number'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. @@ -43,10 +44,12 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n t = []; // Error ~ -!!! error TS2739: Type '[]' is missing the following properties from type '[number, string]': 0, 1 +!!! error TS2322: Type '[]' is not assignable to type '[number, string]'. +!!! error TS2322: Source has 0 element(s) but target requires 2. t = [1]; // Error ~ -!!! error TS2741: Property '1' is missing in type '[number]' but required in type '[number, string]'. +!!! error TS2322: Type '[number]' is not assignable to type '[number, string]'. +!!! error TS2322: Source has 1 element(s) but target requires 2. t = [1, "hello"]; // Ok t = ["hello", 1]; // Error ~~~~~~~ @@ -56,8 +59,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n t = [1, "hello", 2]; // Error ~ !!! error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '3' is not assignable to type '2'. +!!! error TS2322: Source has 3 element(s) but target allows only 2. var tf: [string, (x: string) => number] = ["hello", x => x.length]; diff --git a/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt b/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt index 2ecce8a802ea6..a7aba2e8a676d 100644 --- a/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt +++ b/tests/baselines/reference/unionTypeFromArrayLiteral.errors.txt @@ -1,6 +1,5 @@ tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts(9,5): error TS2322: Type '[number, string, string]' is not assignable to type '[number, string]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + Source has 3 element(s) but target allows only 2. ==== tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts (1 errors) ==== @@ -15,8 +14,7 @@ tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts(9,5): error TS2 var arr4Tuple: [number, string] = [3, "three", "hello"]; // [number, string, string] ~~~~~~~~~ !!! error TS2322: Type '[number, string, string]' is not assignable to type '[number, string]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '3' is not assignable to type '2'. +!!! error TS2322: Source has 3 element(s) but target allows only 2. var arrEmpty = []; var arr5Tuple: { 0: string; diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt new file mode 100644 index 0000000000000..2cb9d46a207c1 --- /dev/null +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -0,0 +1,361 @@ +tests/cases/conformance/types/tuple/variadicTuples1.ts(6,48): error TS1256: A rest element must be last in a tuple type. +tests/cases/conformance/types/tuple/variadicTuples1.ts(46,5): error TS2555: Expected at least 3 arguments, but got 2. +tests/cases/conformance/types/tuple/variadicTuples1.ts(47,17): error TS2345: Argument of type '45' is not assignable to parameter of type 'boolean'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(125,9): error TS2344: Type 'V' does not satisfy the constraint 'unknown[]'. + The type 'readonly unknown[]' is 'readonly' and cannot be assigned to the mutable type 'unknown[]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(143,5): error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...T]'. + Target requires 2 element(s) but source may have fewer. +tests/cases/conformance/types/tuple/variadicTuples1.ts(145,5): error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...U]'. + Target requires 2 element(s) but source may have fewer. +tests/cases/conformance/types/tuple/variadicTuples1.ts(146,5): error TS2322: Type '[string, ...T]' is not assignable to type '[string, ...U]'. + Type 'T' is not assignable to type 'U'. + 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'. + Type 'string[]' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'string[]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(154,5): error TS2322: Type 'readonly [...T]' is not assignable to type 'T'. + 'T' could be instantiated with an arbitrary type which could be unrelated to 'readonly [...T]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(156,5): error TS4104: The type 'readonly [...T]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(163,5): error TS2322: Type 'readonly [...T]' is not assignable to type 'T'. + 'readonly [...T]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'readonly unknown[]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(164,5): error TS2322: Type 'T' is not assignable to type '[...T]'. + The type 'readonly unknown[]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(165,5): error TS4104: The type 'readonly [...T]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(297,14): error TS7019: Rest parameter 'x' implicitly has an 'any[]' type. + + +==== tests/cases/conformance/types/tuple/variadicTuples1.ts (13 errors) ==== + // Variadics in tuple types + + type TV0 = [string, ...T]; + type TV1 = [string, ...T, number]; + type TV2 = [string, ...T, number, ...T]; + type TV3 = [string, ...T, ...number[], ...T]; // Error + ~~~~~~~~~~~ +!!! error TS1256: A rest element must be last in a tuple type. + + // Normalization + + type TN1 = TV1<[boolean, string]>; + type TN2 = TV1<[]>; + type TN3 = TV1<[boolean?]>; + type TN4 = TV1; + type TN5 = TV1<[boolean] | [symbol, symbol]>; + type TN6 = TV1; + type TN7 = TV1; + + // Variadics in array literals + + function tup2(t: [...T], u: [...U]) { + return [1, ...t, 2, ...u, 3] as const; + } + + const t2 = tup2(['hello'], [10, true]); + + function concat(t: [...T], u: [...U]): [...T, ...U] { + return [...t, ...u]; + } + + declare const sa: string[]; + + const tc1 = concat([], []); + const tc2 = concat(['hello'], [42]); + const tc3 = concat([1, 2, 3], sa); + const tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] + + // Spread arguments + + declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; + + function foo2(t1: [number, string], t2: [boolean], a1: number[]) { + foo1(1, 'abc', true, 42, 43, 44); + foo1(...t1, true, 42, 43, 44); + foo1(...t1, ...t2, 42, 43, 44); + foo1(...t1, ...t2, ...a1); + foo1(...t1); // Error + ~~~~~~~~~~~ +!!! error TS2555: Expected at least 3 arguments, but got 2. +!!! related TS6210 tests/cases/conformance/types/tuple/variadicTuples1.ts:39:45: An argument for 'c' was not provided. + foo1(...t1, 45); // Error + ~~ +!!! error TS2345: Argument of type '45' is not assignable to parameter of type 'boolean'. + } + + declare function foo3(x: number, ...args: [...T, number]): T; + + function foo4(u: U) { + foo3(1, 2); + foo3(1, 'hello', true, 2); + foo3(1, ...u, 'hi', 2); + foo3(1); + } + + // Contextual typing of array literals + + declare function ft1(t: T): T; + declare function ft2(t: T): readonly [...T]; + declare function ft3(t: [...T]): T; + declare function ft4(t: [...T]): readonly [...T]; + + ft1(['hello', 42]); // (string | number)[] + ft2(['hello', 42]); // readonly (string | number)[] + ft3(['hello', 42]); // [string, number] + ft4(['hello', 42]); // readonly [string, number] + + // Indexing variadic tuple types + + function f0(t: [string, ...T], n: number) { + const a = t[0]; // string + const b = t[1]; // [string, ...T][1] + const c = t[2]; // [string, ...T][2] + const d = t[n]; // [string, ...T][number] + } + + function f1(t: [string, ...T, number], n: number) { + const a = t[0]; // string + const b = t[1]; // [string, ...T, number][1] + const c = t[2]; // [string, ...T, number][2] + const d = t[n]; // [string, ...T, number][number] + } + + // Destructuring variadic tuple types + + function f2(t: [string, ...T]) { + let [...ax] = t; // [string, ...T] + let [b1, ...bx] = t; // string, [...T] + let [c1, c2, ...cx] = t; // string, [string, ...T][1], T[number][] + } + + function f3(t: [string, ...T, number]) { + let [...ax] = t; // [string, ...T, number] + let [b1, ...bx] = t; // string, [...T, number] + let [c1, c2, ...cx] = t; // string, [string, ...T, number][1], (number | T[number])[] + } + + // Mapped types applied to variadic tuple types + + type Arrayify = { [P in keyof T]: T[P][] }; + + type TM1 = Arrayify; // [string[], (number | undefined)[]?, Arrayify, ...boolean[][]] + + type TP1 = Partial<[string, ...T, number]>; // [string?, Partial, number?] + type TP2 = Partial<[string, ...T, ...number[]]>; // [string?, Partial, ...(number | undefined)[]] + + // Reverse mapping through mapped type applied to variadic tuple type + + declare function fm1(t: Arrayify<[string, number, ...T]>): T; + + let tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] + + // Spread of readonly array-like infers mutable array-like + + declare function fx1(a: string, ...args: T): T; + + function gx1(u: U, v: V) { + fx1('abc'); // [] + fx1('abc', ...u); // U + fx1('abc', ...v); // [...V] + fx1('abc', ...u); // U + fx1('abc', ...v); // Error + ~ +!!! error TS2344: Type 'V' does not satisfy the constraint 'unknown[]'. +!!! error TS2344: The type 'readonly unknown[]' is 'readonly' and cannot be assigned to the mutable type 'unknown[]'. + } + + declare function fx2(a: string, ...args: T): T; + + function gx2(u: U, v: V) { + fx2('abc'); // [] + fx2('abc', ...u); // U + fx2('abc', ...v); // [...V] + fx2('abc', ...u); // U + fx2('abc', ...v); // V + } + + // Relations involving variadic tuple types + + function f10(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) { + x = y; + x = z; + y = x; // Error + ~ +!!! error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...T]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. + y = z; + z = x; // Error + ~ +!!! error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...U]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. + z = y; // Error + ~ +!!! error TS2322: Type '[string, ...T]' is not assignable to type '[string, ...U]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'. +!!! error TS2322: Type 'string[]' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'string[]'. + } + + // For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable + // to [...T] when T is constrained to a mutable array or tuple type. + + function f11(t: T, m: [...T], r: readonly [...T]) { + t = m; + t = r; // Error + ~ +!!! error TS2322: Type 'readonly [...T]' is not assignable to type 'T'. +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'readonly [...T]'. + m = t; + m = r; // Error + ~ +!!! error TS4104: The type 'readonly [...T]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. + r = t; + r = m; + } + + function f12(t: T, m: [...T], r: readonly [...T]) { + t = m; + t = r; // Error + ~ +!!! error TS2322: Type 'readonly [...T]' is not assignable to type 'T'. +!!! error TS2322: 'readonly [...T]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'readonly unknown[]'. + m = t; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type '[...T]'. +!!! error TS2322: The type 'readonly unknown[]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. + m = r; // Error + ~ +!!! error TS4104: The type 'readonly [...T]' is 'readonly' and cannot be assigned to the mutable type '[...T]'. + r = t; + r = m; + } + + // Inference between variadic tuple types + + type First = T[0]; + type DropFirst = T extends readonly [any, ...infer U] ? U : [...T]; + + type Last = T extends readonly [...infer _, infer U] ? U : undefined; + type DropLast = T extends readonly [...infer U, any] ? U : [...T]; + + type T00 = First<[number, symbol, string]>; + type T01 = First<[symbol, string]>; + type T02 = First<[string]>; + type T03 = First<[number, symbol, ...string[]]>; + type T04 = First<[symbol, ...string[]]>; + type T05 = First; + type T06 = First<[]>; + type T07 = First; + type T08 = First; + + type T10 = DropFirst<[number, symbol, string]>; + type T11 = DropFirst<[symbol, string]>; + type T12 = DropFirst<[string]>; + type T13 = DropFirst<[number, symbol, ...string[]]>; + type T14 = DropFirst<[symbol, ...string[]]>; + type T15 = DropFirst; + type T16 = DropFirst<[]>; + type T17 = DropFirst; + type T18 = DropFirst; + + type T20 = Last<[number, symbol, string]>; + type T21 = Last<[symbol, string]>; + type T22 = Last<[string]>; + type T23 = Last<[number, symbol, ...string[]]>; + type T24 = Last<[symbol, ...string[]]>; + type T25 = Last; + type T26 = Last<[]>; // unknown[], maybe should be [] + type T27 = Last; // unknown, maybe should be any + type T28 = Last; + + type T30 = DropLast<[number, symbol, string]>; + type T31 = DropLast<[symbol, string]>; + type T32 = DropLast<[string]>; + type T33 = DropLast<[number, symbol, ...string[]]>; + type T34 = DropLast<[symbol, ...string[]]>; + type T35 = DropLast; + type T36 = DropLast<[]>; // unknown[], maybe should be [] + type T37 = DropLast; + type T38 = DropLast; + + type R00 = First; + type R01 = First; + type R02 = First; + type R03 = First; + type R04 = First; + type R05 = First; + type R06 = First; + + type R10 = DropFirst; + type R11 = DropFirst; + type R12 = DropFirst; + type R13 = DropFirst; + type R14 = DropFirst; + type R15 = DropFirst; + type R16 = DropFirst; + + type R20 = Last; + type R21 = Last; + type R22 = Last; + type R23 = Last; + type R24 = Last; + type R25 = Last; + type R26 = Last; + + type R30 = DropLast; + type R31 = DropLast; + type R32 = DropLast; + type R33 = DropLast; + type R34 = DropLast; + type R35 = DropLast; + type R36 = DropLast; + + // Inference to [...T, ...U] with implied arity for T + + function curry(f: (...args: [...T, ...U]) => R, ...a: T) { + return (...b: U) => f(...a, ...b); + } + + const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; + + const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number + const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number + const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number + const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number + const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number + + const fn2 = (x: number, b: boolean, ...args: string[]) => 0; + + const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number + const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number + const c12 = curry(fn2, 1, true); // (...args: string[]) => number + const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number + + const fn3 = (...args: string[]) => 0; + + const c20 = curry(fn3); // (...args: string[]) => number + const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number + const c22 = curry(fn3, ...sa); // (...args: string[]) => number + + // No inference to [...T, ...U] when there is no implied arity + + function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]) { + return f(...t, ...u); + } + + declare function fn10(a: string, b: number, c: boolean): string[]; + + curry2(fn10, ['hello', 42], [true]); + curry2(fn10, ['hello'], [42, true]); + + // Last argument is contextually typed + + declare function call(...args: [...T, (...args: T) => R]): [T, R]; + + call('hello', 32, (a, b) => 42); + + // Would be nice to infer [...string[], (...args: string[]) => number] here + // Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure + + call(...sa, (...x) => 42); + ~~~~ +!!! error TS7019: Rest parameter 'x' implicitly has an 'any[]' type. + \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples1.js b/tests/baselines/reference/variadicTuples1.js new file mode 100644 index 0000000000000..e35f25830b5a0 --- /dev/null +++ b/tests/baselines/reference/variadicTuples1.js @@ -0,0 +1,599 @@ +//// [variadicTuples1.ts] +// Variadics in tuple types + +type TV0 = [string, ...T]; +type TV1 = [string, ...T, number]; +type TV2 = [string, ...T, number, ...T]; +type TV3 = [string, ...T, ...number[], ...T]; // Error + +// Normalization + +type TN1 = TV1<[boolean, string]>; +type TN2 = TV1<[]>; +type TN3 = TV1<[boolean?]>; +type TN4 = TV1; +type TN5 = TV1<[boolean] | [symbol, symbol]>; +type TN6 = TV1; +type TN7 = TV1; + +// Variadics in array literals + +function tup2(t: [...T], u: [...U]) { + return [1, ...t, 2, ...u, 3] as const; +} + +const t2 = tup2(['hello'], [10, true]); + +function concat(t: [...T], u: [...U]): [...T, ...U] { + return [...t, ...u]; +} + +declare const sa: string[]; + +const tc1 = concat([], []); +const tc2 = concat(['hello'], [42]); +const tc3 = concat([1, 2, 3], sa); +const tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] + +// Spread arguments + +declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; + +function foo2(t1: [number, string], t2: [boolean], a1: number[]) { + foo1(1, 'abc', true, 42, 43, 44); + foo1(...t1, true, 42, 43, 44); + foo1(...t1, ...t2, 42, 43, 44); + foo1(...t1, ...t2, ...a1); + foo1(...t1); // Error + foo1(...t1, 45); // Error +} + +declare function foo3(x: number, ...args: [...T, number]): T; + +function foo4(u: U) { + foo3(1, 2); + foo3(1, 'hello', true, 2); + foo3(1, ...u, 'hi', 2); + foo3(1); +} + +// Contextual typing of array literals + +declare function ft1(t: T): T; +declare function ft2(t: T): readonly [...T]; +declare function ft3(t: [...T]): T; +declare function ft4(t: [...T]): readonly [...T]; + +ft1(['hello', 42]); // (string | number)[] +ft2(['hello', 42]); // readonly (string | number)[] +ft3(['hello', 42]); // [string, number] +ft4(['hello', 42]); // readonly [string, number] + +// Indexing variadic tuple types + +function f0(t: [string, ...T], n: number) { + const a = t[0]; // string + const b = t[1]; // [string, ...T][1] + const c = t[2]; // [string, ...T][2] + const d = t[n]; // [string, ...T][number] +} + +function f1(t: [string, ...T, number], n: number) { + const a = t[0]; // string + const b = t[1]; // [string, ...T, number][1] + const c = t[2]; // [string, ...T, number][2] + const d = t[n]; // [string, ...T, number][number] +} + +// Destructuring variadic tuple types + +function f2(t: [string, ...T]) { + let [...ax] = t; // [string, ...T] + let [b1, ...bx] = t; // string, [...T] + let [c1, c2, ...cx] = t; // string, [string, ...T][1], T[number][] +} + +function f3(t: [string, ...T, number]) { + let [...ax] = t; // [string, ...T, number] + let [b1, ...bx] = t; // string, [...T, number] + let [c1, c2, ...cx] = t; // string, [string, ...T, number][1], (number | T[number])[] +} + +// Mapped types applied to variadic tuple types + +type Arrayify = { [P in keyof T]: T[P][] }; + +type TM1 = Arrayify; // [string[], (number | undefined)[]?, Arrayify, ...boolean[][]] + +type TP1 = Partial<[string, ...T, number]>; // [string?, Partial, number?] +type TP2 = Partial<[string, ...T, ...number[]]>; // [string?, Partial, ...(number | undefined)[]] + +// Reverse mapping through mapped type applied to variadic tuple type + +declare function fm1(t: Arrayify<[string, number, ...T]>): T; + +let tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] + +// Spread of readonly array-like infers mutable array-like + +declare function fx1(a: string, ...args: T): T; + +function gx1(u: U, v: V) { + fx1('abc'); // [] + fx1('abc', ...u); // U + fx1('abc', ...v); // [...V] + fx1('abc', ...u); // U + fx1('abc', ...v); // Error +} + +declare function fx2(a: string, ...args: T): T; + +function gx2(u: U, v: V) { + fx2('abc'); // [] + fx2('abc', ...u); // U + fx2('abc', ...v); // [...V] + fx2('abc', ...u); // U + fx2('abc', ...v); // V +} + +// Relations involving variadic tuple types + +function f10(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) { + x = y; + x = z; + y = x; // Error + y = z; + z = x; // Error + z = y; // Error +} + +// For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable +// to [...T] when T is constrained to a mutable array or tuple type. + +function f11(t: T, m: [...T], r: readonly [...T]) { + t = m; + t = r; // Error + m = t; + m = r; // Error + r = t; + r = m; +} + +function f12(t: T, m: [...T], r: readonly [...T]) { + t = m; + t = r; // Error + m = t; // Error + m = r; // Error + r = t; + r = m; +} + +// Inference between variadic tuple types + +type First = T[0]; +type DropFirst = T extends readonly [any, ...infer U] ? U : [...T]; + +type Last = T extends readonly [...infer _, infer U] ? U : undefined; +type DropLast = T extends readonly [...infer U, any] ? U : [...T]; + +type T00 = First<[number, symbol, string]>; +type T01 = First<[symbol, string]>; +type T02 = First<[string]>; +type T03 = First<[number, symbol, ...string[]]>; +type T04 = First<[symbol, ...string[]]>; +type T05 = First; +type T06 = First<[]>; +type T07 = First; +type T08 = First; + +type T10 = DropFirst<[number, symbol, string]>; +type T11 = DropFirst<[symbol, string]>; +type T12 = DropFirst<[string]>; +type T13 = DropFirst<[number, symbol, ...string[]]>; +type T14 = DropFirst<[symbol, ...string[]]>; +type T15 = DropFirst; +type T16 = DropFirst<[]>; +type T17 = DropFirst; +type T18 = DropFirst; + +type T20 = Last<[number, symbol, string]>; +type T21 = Last<[symbol, string]>; +type T22 = Last<[string]>; +type T23 = Last<[number, symbol, ...string[]]>; +type T24 = Last<[symbol, ...string[]]>; +type T25 = Last; +type T26 = Last<[]>; // unknown[], maybe should be [] +type T27 = Last; // unknown, maybe should be any +type T28 = Last; + +type T30 = DropLast<[number, symbol, string]>; +type T31 = DropLast<[symbol, string]>; +type T32 = DropLast<[string]>; +type T33 = DropLast<[number, symbol, ...string[]]>; +type T34 = DropLast<[symbol, ...string[]]>; +type T35 = DropLast; +type T36 = DropLast<[]>; // unknown[], maybe should be [] +type T37 = DropLast; +type T38 = DropLast; + +type R00 = First; +type R01 = First; +type R02 = First; +type R03 = First; +type R04 = First; +type R05 = First; +type R06 = First; + +type R10 = DropFirst; +type R11 = DropFirst; +type R12 = DropFirst; +type R13 = DropFirst; +type R14 = DropFirst; +type R15 = DropFirst; +type R16 = DropFirst; + +type R20 = Last; +type R21 = Last; +type R22 = Last; +type R23 = Last; +type R24 = Last; +type R25 = Last; +type R26 = Last; + +type R30 = DropLast; +type R31 = DropLast; +type R32 = DropLast; +type R33 = DropLast; +type R34 = DropLast; +type R35 = DropLast; +type R36 = DropLast; + +// Inference to [...T, ...U] with implied arity for T + +function curry(f: (...args: [...T, ...U]) => R, ...a: T) { + return (...b: U) => f(...a, ...b); +} + +const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; + +const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number +const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number +const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number +const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number +const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number + +const fn2 = (x: number, b: boolean, ...args: string[]) => 0; + +const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number +const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number +const c12 = curry(fn2, 1, true); // (...args: string[]) => number +const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number + +const fn3 = (...args: string[]) => 0; + +const c20 = curry(fn3); // (...args: string[]) => number +const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number +const c22 = curry(fn3, ...sa); // (...args: string[]) => number + +// No inference to [...T, ...U] when there is no implied arity + +function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]) { + return f(...t, ...u); +} + +declare function fn10(a: string, b: number, c: boolean): string[]; + +curry2(fn10, ['hello', 42], [true]); +curry2(fn10, ['hello'], [42, true]); + +// Last argument is contextually typed + +declare function call(...args: [...T, (...args: T) => R]): [T, R]; + +call('hello', 32, (a, b) => 42); + +// Would be nice to infer [...string[], (...args: string[]) => number] here +// Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure + +call(...sa, (...x) => 42); + + +//// [variadicTuples1.js] +"use strict"; +// Variadics in tuple types +var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; +// Variadics in array literals +function tup2(t, u) { + return __spreadArrays([1], t, [2], u, [3]); +} +var t2 = tup2(['hello'], [10, true]); +function concat(t, u) { + return __spreadArrays(t, u); +} +var tc1 = concat([], []); +var tc2 = concat(['hello'], [42]); +var tc3 = concat([1, 2, 3], sa); +var tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] +function foo2(t1, t2, a1) { + foo1(1, 'abc', true, 42, 43, 44); + foo1.apply(void 0, __spreadArrays(t1, [true, 42, 43, 44])); + foo1.apply(void 0, __spreadArrays(t1, t2, [42, 43, 44])); + foo1.apply(void 0, __spreadArrays(t1, t2, a1)); + foo1.apply(void 0, t1); // Error + foo1.apply(void 0, __spreadArrays(t1, [45])); // Error +} +function foo4(u) { + foo3(1, 2); + foo3(1, 'hello', true, 2); + foo3.apply(void 0, __spreadArrays([1], u, ['hi', 2])); + foo3(1); +} +ft1(['hello', 42]); // (string | number)[] +ft2(['hello', 42]); // readonly (string | number)[] +ft3(['hello', 42]); // [string, number] +ft4(['hello', 42]); // readonly [string, number] +// Indexing variadic tuple types +function f0(t, n) { + var a = t[0]; // string + var b = t[1]; // [string, ...T][1] + var c = t[2]; // [string, ...T][2] + var d = t[n]; // [string, ...T][number] +} +function f1(t, n) { + var a = t[0]; // string + var b = t[1]; // [string, ...T, number][1] + var c = t[2]; // [string, ...T, number][2] + var d = t[n]; // [string, ...T, number][number] +} +// Destructuring variadic tuple types +function f2(t) { + var ax = t.slice(0); // [string, ...T] + var b1 = t[0], bx = t.slice(1); // string, [...T] + var c1 = t[0], c2 = t[1], cx = t.slice(2); // string, [string, ...T][1], T[number][] +} +function f3(t) { + var ax = t.slice(0); // [string, ...T, number] + var b1 = t[0], bx = t.slice(1); // string, [...T, number] + var c1 = t[0], c2 = t[1], cx = t.slice(2); // string, [string, ...T, number][1], (number | T[number])[] +} +var tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] +function gx1(u, v) { + fx1('abc'); // [] + fx1.apply(void 0, __spreadArrays(['abc'], u)); // U + fx1.apply(void 0, __spreadArrays(['abc'], v)); // [...V] + fx1.apply(void 0, __spreadArrays(['abc'], u)); // U + fx1.apply(void 0, __spreadArrays(['abc'], v)); // Error +} +function gx2(u, v) { + fx2('abc'); // [] + fx2.apply(void 0, __spreadArrays(['abc'], u)); // U + fx2.apply(void 0, __spreadArrays(['abc'], v)); // [...V] + fx2.apply(void 0, __spreadArrays(['abc'], u)); // U + fx2.apply(void 0, __spreadArrays(['abc'], v)); // V +} +// Relations involving variadic tuple types +function f10(x, y, z) { + x = y; + x = z; + y = x; // Error + y = z; + z = x; // Error + z = y; // Error +} +// For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable +// to [...T] when T is constrained to a mutable array or tuple type. +function f11(t, m, r) { + t = m; + t = r; // Error + m = t; + m = r; // Error + r = t; + r = m; +} +function f12(t, m, r) { + t = m; + t = r; // Error + m = t; // Error + m = r; // Error + r = t; + r = m; +} +// Inference to [...T, ...U] with implied arity for T +function curry(f) { + var a = []; + for (var _i = 1; _i < arguments.length; _i++) { + a[_i - 1] = arguments[_i]; + } + return function () { + var b = []; + for (var _i = 0; _i < arguments.length; _i++) { + b[_i] = arguments[_i]; + } + return f.apply(void 0, __spreadArrays(a, b)); + }; +} +var fn1 = function (a, b, c, d) { return 0; }; +var c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number +var c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number +var c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number +var c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number +var c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number +var fn2 = function (x, b) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + return 0; +}; +var c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number +var c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number +var c12 = curry(fn2, 1, true); // (...args: string[]) => number +var c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number +var fn3 = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return 0; +}; +var c20 = curry(fn3); // (...args: string[]) => number +var c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number +var c22 = curry.apply(void 0, __spreadArrays([fn3], sa)); // (...args: string[]) => number +// No inference to [...T, ...U] when there is no implied arity +function curry2(f, t, u) { + return f.apply(void 0, __spreadArrays(t, u)); +} +curry2(fn10, ['hello', 42], [true]); +curry2(fn10, ['hello'], [42, true]); +call('hello', 32, function (a, b) { return 42; }); +// Would be nice to infer [...string[], (...args: string[]) => number] here +// Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure +call.apply(void 0, __spreadArrays(sa, [function () { + var x = []; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i] = arguments[_i]; + } + return 42; + }])); + + +//// [variadicTuples1.d.ts] +declare type TV0 = [string, ...T]; +declare type TV1 = [string, ...T, number]; +declare type TV2 = [string, ...T, number, ...T]; +declare type TV3 = [string, ...T, ...number[], ...T]; +declare type TN1 = TV1<[boolean, string]>; +declare type TN2 = TV1<[]>; +declare type TN3 = TV1<[boolean?]>; +declare type TN4 = TV1; +declare type TN5 = TV1<[boolean] | [symbol, symbol]>; +declare type TN6 = TV1; +declare type TN7 = TV1; +declare function tup2(t: [...T], u: [...U]): readonly [1, ...T, 2, ...U, 3]; +declare const t2: readonly [1, string, 2, number, boolean, 3]; +declare function concat(t: [...T], u: [...U]): [...T, ...U]; +declare const sa: string[]; +declare const tc1: []; +declare const tc2: [string, number]; +declare const tc3: [number, number, number, ...string[]]; +declare const tc4: (string | number)[]; +declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; +declare function foo2(t1: [number, string], t2: [boolean], a1: number[]): void; +declare function foo3(x: number, ...args: [...T, number]): T; +declare function foo4(u: U): void; +declare function ft1(t: T): T; +declare function ft2(t: T): readonly [...T]; +declare function ft3(t: [...T]): T; +declare function ft4(t: [...T]): readonly [...T]; +declare function f0(t: [string, ...T], n: number): void; +declare function f1(t: [string, ...T, number], n: number): void; +declare function f2(t: [string, ...T]): void; +declare function f3(t: [string, ...T, number]): void; +declare type Arrayify = { + [P in keyof T]: T[P][]; +}; +declare type TM1 = Arrayify; +declare type TP1 = Partial<[string, ...T, number]>; +declare type TP2 = Partial<[string, ...T, ...number[]]>; +declare function fm1(t: Arrayify<[string, number, ...T]>): T; +declare let tm1: [boolean, string]; +declare function fx1(a: string, ...args: T): T; +declare function gx1(u: U, v: V): void; +declare function fx2(a: string, ...args: T): T; +declare function gx2(u: U, v: V): void; +declare function f10(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]): void; +declare function f11(t: T, m: [...T], r: readonly [...T]): void; +declare function f12(t: T, m: [...T], r: readonly [...T]): void; +declare type First = T[0]; +declare type DropFirst = T extends readonly [any, ...infer U] ? U : [...T]; +declare type Last = T extends readonly [...infer _, infer U] ? U : undefined; +declare type DropLast = T extends readonly [...infer U, any] ? U : [...T]; +declare type T00 = First<[number, symbol, string]>; +declare type T01 = First<[symbol, string]>; +declare type T02 = First<[string]>; +declare type T03 = First<[number, symbol, ...string[]]>; +declare type T04 = First<[symbol, ...string[]]>; +declare type T05 = First; +declare type T06 = First<[]>; +declare type T07 = First; +declare type T08 = First; +declare type T10 = DropFirst<[number, symbol, string]>; +declare type T11 = DropFirst<[symbol, string]>; +declare type T12 = DropFirst<[string]>; +declare type T13 = DropFirst<[number, symbol, ...string[]]>; +declare type T14 = DropFirst<[symbol, ...string[]]>; +declare type T15 = DropFirst; +declare type T16 = DropFirst<[]>; +declare type T17 = DropFirst; +declare type T18 = DropFirst; +declare type T20 = Last<[number, symbol, string]>; +declare type T21 = Last<[symbol, string]>; +declare type T22 = Last<[string]>; +declare type T23 = Last<[number, symbol, ...string[]]>; +declare type T24 = Last<[symbol, ...string[]]>; +declare type T25 = Last; +declare type T26 = Last<[]>; +declare type T27 = Last; +declare type T28 = Last; +declare type T30 = DropLast<[number, symbol, string]>; +declare type T31 = DropLast<[symbol, string]>; +declare type T32 = DropLast<[string]>; +declare type T33 = DropLast<[number, symbol, ...string[]]>; +declare type T34 = DropLast<[symbol, ...string[]]>; +declare type T35 = DropLast; +declare type T36 = DropLast<[]>; +declare type T37 = DropLast; +declare type T38 = DropLast; +declare type R00 = First; +declare type R01 = First; +declare type R02 = First; +declare type R03 = First; +declare type R04 = First; +declare type R05 = First; +declare type R06 = First; +declare type R10 = DropFirst; +declare type R11 = DropFirst; +declare type R12 = DropFirst; +declare type R13 = DropFirst; +declare type R14 = DropFirst; +declare type R15 = DropFirst; +declare type R16 = DropFirst; +declare type R20 = Last; +declare type R21 = Last; +declare type R22 = Last; +declare type R23 = Last; +declare type R24 = Last; +declare type R25 = Last; +declare type R26 = Last; +declare type R30 = DropLast; +declare type R31 = DropLast; +declare type R32 = DropLast; +declare type R33 = DropLast; +declare type R34 = DropLast; +declare type R35 = DropLast; +declare type R36 = DropLast; +declare function curry(f: (...args: [...T, ...U]) => R, ...a: T): (...b: U) => R; +declare const fn1: (a: number, b: string, c: boolean, d: string[]) => number; +declare const c0: (a: number, b: string, c: boolean, d: string[]) => number; +declare const c1: (b: string, c: boolean, d: string[]) => number; +declare const c2: (c: boolean, d: string[]) => number; +declare const c3: (d: string[]) => number; +declare const c4: () => number; +declare const fn2: (x: number, b: boolean, ...args: string[]) => number; +declare const c10: (x: number, b: boolean, ...args: string[]) => number; +declare const c11: (b: boolean, ...args: string[]) => number; +declare const c12: (...b: string[]) => number; +declare const c13: (...b: string[]) => number; +declare const fn3: (...args: string[]) => number; +declare const c20: (...b: string[]) => number; +declare const c21: (...b: string[]) => number; +declare const c22: (...b: string[]) => number; +declare function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]): R; +declare function fn10(a: string, b: number, c: boolean): string[]; +declare function call(...args: [...T, (...args: T) => R]): [T, R]; diff --git a/tests/baselines/reference/variadicTuples1.symbols b/tests/baselines/reference/variadicTuples1.symbols new file mode 100644 index 0000000000000..4701211779bf4 --- /dev/null +++ b/tests/baselines/reference/variadicTuples1.symbols @@ -0,0 +1,1009 @@ +=== tests/cases/conformance/types/tuple/variadicTuples1.ts === +// Variadics in tuple types + +type TV0 = [string, ...T]; +>TV0 : Symbol(TV0, Decl(variadicTuples1.ts, 0, 0)) +>T : Symbol(T, Decl(variadicTuples1.ts, 2, 9)) +>T : Symbol(T, Decl(variadicTuples1.ts, 2, 9)) + +type TV1 = [string, ...T, number]; +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 3, 9)) +>T : Symbol(T, Decl(variadicTuples1.ts, 3, 9)) + +type TV2 = [string, ...T, number, ...T]; +>TV2 : Symbol(TV2, Decl(variadicTuples1.ts, 3, 55)) +>T : Symbol(T, Decl(variadicTuples1.ts, 4, 9)) +>T : Symbol(T, Decl(variadicTuples1.ts, 4, 9)) +>T : Symbol(T, Decl(variadicTuples1.ts, 4, 9)) + +type TV3 = [string, ...T, ...number[], ...T]; // Error +>TV3 : Symbol(TV3, Decl(variadicTuples1.ts, 4, 61)) +>T : Symbol(T, Decl(variadicTuples1.ts, 5, 9)) +>T : Symbol(T, Decl(variadicTuples1.ts, 5, 9)) +>T : Symbol(T, Decl(variadicTuples1.ts, 5, 9)) + +// Normalization + +type TN1 = TV1<[boolean, string]>; +>TN1 : Symbol(TN1, Decl(variadicTuples1.ts, 5, 66)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +type TN2 = TV1<[]>; +>TN2 : Symbol(TN2, Decl(variadicTuples1.ts, 9, 34)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +type TN3 = TV1<[boolean?]>; +>TN3 : Symbol(TN3, Decl(variadicTuples1.ts, 10, 19)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +type TN4 = TV1; +>TN4 : Symbol(TN4, Decl(variadicTuples1.ts, 11, 27)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +type TN5 = TV1<[boolean] | [symbol, symbol]>; +>TN5 : Symbol(TN5, Decl(variadicTuples1.ts, 12, 25)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +type TN6 = TV1; +>TN6 : Symbol(TN6, Decl(variadicTuples1.ts, 13, 45)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +type TN7 = TV1; +>TN7 : Symbol(TN7, Decl(variadicTuples1.ts, 14, 20)) +>TV1 : Symbol(TV1, Decl(variadicTuples1.ts, 2, 47)) + +// Variadics in array literals + +function tup2(t: [...T], u: [...U]) { +>tup2 : Symbol(tup2, Decl(variadicTuples1.ts, 15, 22)) +>T : Symbol(T, Decl(variadicTuples1.ts, 19, 14)) +>U : Symbol(U, Decl(variadicTuples1.ts, 19, 34)) +>t : Symbol(t, Decl(variadicTuples1.ts, 19, 56)) +>T : Symbol(T, Decl(variadicTuples1.ts, 19, 14)) +>u : Symbol(u, Decl(variadicTuples1.ts, 19, 66)) +>U : Symbol(U, Decl(variadicTuples1.ts, 19, 34)) + + return [1, ...t, 2, ...u, 3] as const; +>t : Symbol(t, Decl(variadicTuples1.ts, 19, 56)) +>u : Symbol(u, Decl(variadicTuples1.ts, 19, 66)) +} + +const t2 = tup2(['hello'], [10, true]); +>t2 : Symbol(t2, Decl(variadicTuples1.ts, 23, 5)) +>tup2 : Symbol(tup2, Decl(variadicTuples1.ts, 15, 22)) + +function concat(t: [...T], u: [...U]): [...T, ...U] { +>concat : Symbol(concat, Decl(variadicTuples1.ts, 23, 39)) +>T : Symbol(T, Decl(variadicTuples1.ts, 25, 16)) +>U : Symbol(U, Decl(variadicTuples1.ts, 25, 36)) +>t : Symbol(t, Decl(variadicTuples1.ts, 25, 58)) +>T : Symbol(T, Decl(variadicTuples1.ts, 25, 16)) +>u : Symbol(u, Decl(variadicTuples1.ts, 25, 68)) +>U : Symbol(U, Decl(variadicTuples1.ts, 25, 36)) +>T : Symbol(T, Decl(variadicTuples1.ts, 25, 16)) +>U : Symbol(U, Decl(variadicTuples1.ts, 25, 36)) + + return [...t, ...u]; +>t : Symbol(t, Decl(variadicTuples1.ts, 25, 58)) +>u : Symbol(u, Decl(variadicTuples1.ts, 25, 68)) +} + +declare const sa: string[]; +>sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) + +const tc1 = concat([], []); +>tc1 : Symbol(tc1, Decl(variadicTuples1.ts, 31, 5)) +>concat : Symbol(concat, Decl(variadicTuples1.ts, 23, 39)) + +const tc2 = concat(['hello'], [42]); +>tc2 : Symbol(tc2, Decl(variadicTuples1.ts, 32, 5)) +>concat : Symbol(concat, Decl(variadicTuples1.ts, 23, 39)) + +const tc3 = concat([1, 2, 3], sa); +>tc3 : Symbol(tc3, Decl(variadicTuples1.ts, 33, 5)) +>concat : Symbol(concat, Decl(variadicTuples1.ts, 23, 39)) +>sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) + +const tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] +>tc4 : Symbol(tc4, Decl(variadicTuples1.ts, 34, 5)) +>concat : Symbol(concat, Decl(variadicTuples1.ts, 23, 39)) +>sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) + +// Spread arguments + +declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) +>a : Symbol(a, Decl(variadicTuples1.ts, 38, 22)) +>b : Symbol(b, Decl(variadicTuples1.ts, 38, 32)) +>c : Symbol(c, Decl(variadicTuples1.ts, 38, 43)) +>d : Symbol(d, Decl(variadicTuples1.ts, 38, 55)) + +function foo2(t1: [number, string], t2: [boolean], a1: number[]) { +>foo2 : Symbol(foo2, Decl(variadicTuples1.ts, 38, 78)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 40, 14)) +>t2 : Symbol(t2, Decl(variadicTuples1.ts, 40, 35)) +>a1 : Symbol(a1, Decl(variadicTuples1.ts, 40, 50)) + + foo1(1, 'abc', true, 42, 43, 44); +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) + + foo1(...t1, true, 42, 43, 44); +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 40, 14)) + + foo1(...t1, ...t2, 42, 43, 44); +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 40, 14)) +>t2 : Symbol(t2, Decl(variadicTuples1.ts, 40, 35)) + + foo1(...t1, ...t2, ...a1); +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 40, 14)) +>t2 : Symbol(t2, Decl(variadicTuples1.ts, 40, 35)) +>a1 : Symbol(a1, Decl(variadicTuples1.ts, 40, 50)) + + foo1(...t1); // Error +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 40, 14)) + + foo1(...t1, 45); // Error +>foo1 : Symbol(foo1, Decl(variadicTuples1.ts, 34, 34)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 40, 14)) +} + +declare function foo3(x: number, ...args: [...T, number]): T; +>foo3 : Symbol(foo3, Decl(variadicTuples1.ts, 47, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 49, 22)) +>x : Symbol(x, Decl(variadicTuples1.ts, 49, 43)) +>args : Symbol(args, Decl(variadicTuples1.ts, 49, 53)) +>T : Symbol(T, Decl(variadicTuples1.ts, 49, 22)) +>T : Symbol(T, Decl(variadicTuples1.ts, 49, 22)) + +function foo4(u: U) { +>foo4 : Symbol(foo4, Decl(variadicTuples1.ts, 49, 82)) +>U : Symbol(U, Decl(variadicTuples1.ts, 51, 14)) +>u : Symbol(u, Decl(variadicTuples1.ts, 51, 35)) +>U : Symbol(U, Decl(variadicTuples1.ts, 51, 14)) + + foo3(1, 2); +>foo3 : Symbol(foo3, Decl(variadicTuples1.ts, 47, 1)) + + foo3(1, 'hello', true, 2); +>foo3 : Symbol(foo3, Decl(variadicTuples1.ts, 47, 1)) + + foo3(1, ...u, 'hi', 2); +>foo3 : Symbol(foo3, Decl(variadicTuples1.ts, 47, 1)) +>u : Symbol(u, Decl(variadicTuples1.ts, 51, 35)) + + foo3(1); +>foo3 : Symbol(foo3, Decl(variadicTuples1.ts, 47, 1)) +} + +// Contextual typing of array literals + +declare function ft1(t: T): T; +>ft1 : Symbol(ft1, Decl(variadicTuples1.ts, 56, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 60, 21)) +>t : Symbol(t, Decl(variadicTuples1.ts, 60, 42)) +>T : Symbol(T, Decl(variadicTuples1.ts, 60, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 60, 21)) + +declare function ft2(t: T): readonly [...T]; +>ft2 : Symbol(ft2, Decl(variadicTuples1.ts, 60, 51)) +>T : Symbol(T, Decl(variadicTuples1.ts, 61, 21)) +>t : Symbol(t, Decl(variadicTuples1.ts, 61, 42)) +>T : Symbol(T, Decl(variadicTuples1.ts, 61, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 61, 21)) + +declare function ft3(t: [...T]): T; +>ft3 : Symbol(ft3, Decl(variadicTuples1.ts, 61, 65)) +>T : Symbol(T, Decl(variadicTuples1.ts, 62, 21)) +>t : Symbol(t, Decl(variadicTuples1.ts, 62, 42)) +>T : Symbol(T, Decl(variadicTuples1.ts, 62, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 62, 21)) + +declare function ft4(t: [...T]): readonly [...T]; +>ft4 : Symbol(ft4, Decl(variadicTuples1.ts, 62, 56)) +>T : Symbol(T, Decl(variadicTuples1.ts, 63, 21)) +>t : Symbol(t, Decl(variadicTuples1.ts, 63, 42)) +>T : Symbol(T, Decl(variadicTuples1.ts, 63, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 63, 21)) + +ft1(['hello', 42]); // (string | number)[] +>ft1 : Symbol(ft1, Decl(variadicTuples1.ts, 56, 1)) + +ft2(['hello', 42]); // readonly (string | number)[] +>ft2 : Symbol(ft2, Decl(variadicTuples1.ts, 60, 51)) + +ft3(['hello', 42]); // [string, number] +>ft3 : Symbol(ft3, Decl(variadicTuples1.ts, 61, 65)) + +ft4(['hello', 42]); // readonly [string, number] +>ft4 : Symbol(ft4, Decl(variadicTuples1.ts, 62, 56)) + +// Indexing variadic tuple types + +function f0(t: [string, ...T], n: number) { +>f0 : Symbol(f0, Decl(variadicTuples1.ts, 68, 19)) +>T : Symbol(T, Decl(variadicTuples1.ts, 72, 12)) +>t : Symbol(t, Decl(variadicTuples1.ts, 72, 33)) +>T : Symbol(T, Decl(variadicTuples1.ts, 72, 12)) +>n : Symbol(n, Decl(variadicTuples1.ts, 72, 51)) + + const a = t[0]; // string +>a : Symbol(a, Decl(variadicTuples1.ts, 73, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 72, 33)) +>0 : Symbol(0) + + const b = t[1]; // [string, ...T][1] +>b : Symbol(b, Decl(variadicTuples1.ts, 74, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 72, 33)) + + const c = t[2]; // [string, ...T][2] +>c : Symbol(c, Decl(variadicTuples1.ts, 75, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 72, 33)) + + const d = t[n]; // [string, ...T][number] +>d : Symbol(d, Decl(variadicTuples1.ts, 76, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 72, 33)) +>n : Symbol(n, Decl(variadicTuples1.ts, 72, 51)) +} + +function f1(t: [string, ...T, number], n: number) { +>f1 : Symbol(f1, Decl(variadicTuples1.ts, 77, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 79, 12)) +>t : Symbol(t, Decl(variadicTuples1.ts, 79, 33)) +>T : Symbol(T, Decl(variadicTuples1.ts, 79, 12)) +>n : Symbol(n, Decl(variadicTuples1.ts, 79, 59)) + + const a = t[0]; // string +>a : Symbol(a, Decl(variadicTuples1.ts, 80, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 79, 33)) +>0 : Symbol(0) + + const b = t[1]; // [string, ...T, number][1] +>b : Symbol(b, Decl(variadicTuples1.ts, 81, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 79, 33)) + + const c = t[2]; // [string, ...T, number][2] +>c : Symbol(c, Decl(variadicTuples1.ts, 82, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 79, 33)) + + const d = t[n]; // [string, ...T, number][number] +>d : Symbol(d, Decl(variadicTuples1.ts, 83, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 79, 33)) +>n : Symbol(n, Decl(variadicTuples1.ts, 79, 59)) +} + +// Destructuring variadic tuple types + +function f2(t: [string, ...T]) { +>f2 : Symbol(f2, Decl(variadicTuples1.ts, 84, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 88, 12)) +>t : Symbol(t, Decl(variadicTuples1.ts, 88, 33)) +>T : Symbol(T, Decl(variadicTuples1.ts, 88, 12)) + + let [...ax] = t; // [string, ...T] +>ax : Symbol(ax, Decl(variadicTuples1.ts, 89, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 88, 33)) + + let [b1, ...bx] = t; // string, [...T] +>b1 : Symbol(b1, Decl(variadicTuples1.ts, 90, 9)) +>bx : Symbol(bx, Decl(variadicTuples1.ts, 90, 12)) +>t : Symbol(t, Decl(variadicTuples1.ts, 88, 33)) + + let [c1, c2, ...cx] = t; // string, [string, ...T][1], T[number][] +>c1 : Symbol(c1, Decl(variadicTuples1.ts, 91, 9)) +>c2 : Symbol(c2, Decl(variadicTuples1.ts, 91, 12)) +>cx : Symbol(cx, Decl(variadicTuples1.ts, 91, 16)) +>t : Symbol(t, Decl(variadicTuples1.ts, 88, 33)) +} + +function f3(t: [string, ...T, number]) { +>f3 : Symbol(f3, Decl(variadicTuples1.ts, 92, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 94, 12)) +>t : Symbol(t, Decl(variadicTuples1.ts, 94, 33)) +>T : Symbol(T, Decl(variadicTuples1.ts, 94, 12)) + + let [...ax] = t; // [string, ...T, number] +>ax : Symbol(ax, Decl(variadicTuples1.ts, 95, 9)) +>t : Symbol(t, Decl(variadicTuples1.ts, 94, 33)) + + let [b1, ...bx] = t; // string, [...T, number] +>b1 : Symbol(b1, Decl(variadicTuples1.ts, 96, 9)) +>bx : Symbol(bx, Decl(variadicTuples1.ts, 96, 12)) +>t : Symbol(t, Decl(variadicTuples1.ts, 94, 33)) + + let [c1, c2, ...cx] = t; // string, [string, ...T, number][1], (number | T[number])[] +>c1 : Symbol(c1, Decl(variadicTuples1.ts, 97, 9)) +>c2 : Symbol(c2, Decl(variadicTuples1.ts, 97, 12)) +>cx : Symbol(cx, Decl(variadicTuples1.ts, 97, 16)) +>t : Symbol(t, Decl(variadicTuples1.ts, 94, 33)) +} + +// Mapped types applied to variadic tuple types + +type Arrayify = { [P in keyof T]: T[P][] }; +>Arrayify : Symbol(Arrayify, Decl(variadicTuples1.ts, 98, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 102, 14)) +>P : Symbol(P, Decl(variadicTuples1.ts, 102, 22)) +>T : Symbol(T, Decl(variadicTuples1.ts, 102, 14)) +>T : Symbol(T, Decl(variadicTuples1.ts, 102, 14)) +>P : Symbol(P, Decl(variadicTuples1.ts, 102, 22)) + +type TM1 = Arrayify; // [string[], (number | undefined)[]?, Arrayify, ...boolean[][]] +>TM1 : Symbol(TM1, Decl(variadicTuples1.ts, 102, 46)) +>U : Symbol(U, Decl(variadicTuples1.ts, 104, 9)) +>Arrayify : Symbol(Arrayify, Decl(variadicTuples1.ts, 98, 1)) +>U : Symbol(U, Decl(variadicTuples1.ts, 104, 9)) + +type TP1 = Partial<[string, ...T, number]>; // [string?, Partial, number?] +>TP1 : Symbol(TP1, Decl(variadicTuples1.ts, 104, 89)) +>T : Symbol(T, Decl(variadicTuples1.ts, 106, 9)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(variadicTuples1.ts, 106, 9)) + +type TP2 = Partial<[string, ...T, ...number[]]>; // [string?, Partial, ...(number | undefined)[]] +>TP2 : Symbol(TP2, Decl(variadicTuples1.ts, 106, 64)) +>T : Symbol(T, Decl(variadicTuples1.ts, 107, 9)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(variadicTuples1.ts, 107, 9)) + +// Reverse mapping through mapped type applied to variadic tuple type + +declare function fm1(t: Arrayify<[string, number, ...T]>): T; +>fm1 : Symbol(fm1, Decl(variadicTuples1.ts, 107, 69)) +>T : Symbol(T, Decl(variadicTuples1.ts, 111, 21)) +>t : Symbol(t, Decl(variadicTuples1.ts, 111, 42)) +>Arrayify : Symbol(Arrayify, Decl(variadicTuples1.ts, 98, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 111, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 111, 21)) + +let tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] +>tm1 : Symbol(tm1, Decl(variadicTuples1.ts, 113, 3)) +>fm1 : Symbol(fm1, Decl(variadicTuples1.ts, 107, 69)) + +// Spread of readonly array-like infers mutable array-like + +declare function fx1(a: string, ...args: T): T; +>fx1 : Symbol(fx1, Decl(variadicTuples1.ts, 113, 48)) +>T : Symbol(T, Decl(variadicTuples1.ts, 117, 21)) +>a : Symbol(a, Decl(variadicTuples1.ts, 117, 42)) +>args : Symbol(args, Decl(variadicTuples1.ts, 117, 52)) +>T : Symbol(T, Decl(variadicTuples1.ts, 117, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 117, 21)) + +function gx1(u: U, v: V) { +>gx1 : Symbol(gx1, Decl(variadicTuples1.ts, 117, 68)) +>U : Symbol(U, Decl(variadicTuples1.ts, 119, 13)) +>V : Symbol(V, Decl(variadicTuples1.ts, 119, 33)) +>u : Symbol(u, Decl(variadicTuples1.ts, 119, 64)) +>U : Symbol(U, Decl(variadicTuples1.ts, 119, 13)) +>v : Symbol(v, Decl(variadicTuples1.ts, 119, 69)) +>V : Symbol(V, Decl(variadicTuples1.ts, 119, 33)) + + fx1('abc'); // [] +>fx1 : Symbol(fx1, Decl(variadicTuples1.ts, 113, 48)) + + fx1('abc', ...u); // U +>fx1 : Symbol(fx1, Decl(variadicTuples1.ts, 113, 48)) +>u : Symbol(u, Decl(variadicTuples1.ts, 119, 64)) + + fx1('abc', ...v); // [...V] +>fx1 : Symbol(fx1, Decl(variadicTuples1.ts, 113, 48)) +>v : Symbol(v, Decl(variadicTuples1.ts, 119, 69)) + + fx1('abc', ...u); // U +>fx1 : Symbol(fx1, Decl(variadicTuples1.ts, 113, 48)) +>U : Symbol(U, Decl(variadicTuples1.ts, 119, 13)) +>u : Symbol(u, Decl(variadicTuples1.ts, 119, 64)) + + fx1('abc', ...v); // Error +>fx1 : Symbol(fx1, Decl(variadicTuples1.ts, 113, 48)) +>V : Symbol(V, Decl(variadicTuples1.ts, 119, 33)) +>v : Symbol(v, Decl(variadicTuples1.ts, 119, 69)) +} + +declare function fx2(a: string, ...args: T): T; +>fx2 : Symbol(fx2, Decl(variadicTuples1.ts, 125, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 127, 21)) +>a : Symbol(a, Decl(variadicTuples1.ts, 127, 51)) +>args : Symbol(args, Decl(variadicTuples1.ts, 127, 61)) +>T : Symbol(T, Decl(variadicTuples1.ts, 127, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 127, 21)) + +function gx2(u: U, v: V) { +>gx2 : Symbol(gx2, Decl(variadicTuples1.ts, 127, 77)) +>U : Symbol(U, Decl(variadicTuples1.ts, 129, 13)) +>V : Symbol(V, Decl(variadicTuples1.ts, 129, 33)) +>u : Symbol(u, Decl(variadicTuples1.ts, 129, 64)) +>U : Symbol(U, Decl(variadicTuples1.ts, 129, 13)) +>v : Symbol(v, Decl(variadicTuples1.ts, 129, 69)) +>V : Symbol(V, Decl(variadicTuples1.ts, 129, 33)) + + fx2('abc'); // [] +>fx2 : Symbol(fx2, Decl(variadicTuples1.ts, 125, 1)) + + fx2('abc', ...u); // U +>fx2 : Symbol(fx2, Decl(variadicTuples1.ts, 125, 1)) +>u : Symbol(u, Decl(variadicTuples1.ts, 129, 64)) + + fx2('abc', ...v); // [...V] +>fx2 : Symbol(fx2, Decl(variadicTuples1.ts, 125, 1)) +>v : Symbol(v, Decl(variadicTuples1.ts, 129, 69)) + + fx2('abc', ...u); // U +>fx2 : Symbol(fx2, Decl(variadicTuples1.ts, 125, 1)) +>U : Symbol(U, Decl(variadicTuples1.ts, 129, 13)) +>u : Symbol(u, Decl(variadicTuples1.ts, 129, 64)) + + fx2('abc', ...v); // V +>fx2 : Symbol(fx2, Decl(variadicTuples1.ts, 125, 1)) +>V : Symbol(V, Decl(variadicTuples1.ts, 129, 33)) +>v : Symbol(v, Decl(variadicTuples1.ts, 129, 69)) +} + +// Relations involving variadic tuple types + +function f10(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) { +>f10 : Symbol(f10, Decl(variadicTuples1.ts, 135, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 139, 13)) +>U : Symbol(U, Decl(variadicTuples1.ts, 139, 32)) +>T : Symbol(T, Decl(variadicTuples1.ts, 139, 13)) +>x : Symbol(x, Decl(variadicTuples1.ts, 139, 46)) +>y : Symbol(y, Decl(variadicTuples1.ts, 139, 72)) +>T : Symbol(T, Decl(variadicTuples1.ts, 139, 13)) +>z : Symbol(z, Decl(variadicTuples1.ts, 139, 91)) +>U : Symbol(U, Decl(variadicTuples1.ts, 139, 32)) + + x = y; +>x : Symbol(x, Decl(variadicTuples1.ts, 139, 46)) +>y : Symbol(y, Decl(variadicTuples1.ts, 139, 72)) + + x = z; +>x : Symbol(x, Decl(variadicTuples1.ts, 139, 46)) +>z : Symbol(z, Decl(variadicTuples1.ts, 139, 91)) + + y = x; // Error +>y : Symbol(y, Decl(variadicTuples1.ts, 139, 72)) +>x : Symbol(x, Decl(variadicTuples1.ts, 139, 46)) + + y = z; +>y : Symbol(y, Decl(variadicTuples1.ts, 139, 72)) +>z : Symbol(z, Decl(variadicTuples1.ts, 139, 91)) + + z = x; // Error +>z : Symbol(z, Decl(variadicTuples1.ts, 139, 91)) +>x : Symbol(x, Decl(variadicTuples1.ts, 139, 46)) + + z = y; // Error +>z : Symbol(z, Decl(variadicTuples1.ts, 139, 91)) +>y : Symbol(y, Decl(variadicTuples1.ts, 139, 72)) +} + +// For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable +// to [...T] when T is constrained to a mutable array or tuple type. + +function f11(t: T, m: [...T], r: readonly [...T]) { +>f11 : Symbol(f11, Decl(variadicTuples1.ts, 146, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 151, 13)) +>t : Symbol(t, Decl(variadicTuples1.ts, 151, 34)) +>T : Symbol(T, Decl(variadicTuples1.ts, 151, 13)) +>m : Symbol(m, Decl(variadicTuples1.ts, 151, 39)) +>T : Symbol(T, Decl(variadicTuples1.ts, 151, 13)) +>r : Symbol(r, Decl(variadicTuples1.ts, 151, 50)) +>T : Symbol(T, Decl(variadicTuples1.ts, 151, 13)) + + t = m; +>t : Symbol(t, Decl(variadicTuples1.ts, 151, 34)) +>m : Symbol(m, Decl(variadicTuples1.ts, 151, 39)) + + t = r; // Error +>t : Symbol(t, Decl(variadicTuples1.ts, 151, 34)) +>r : Symbol(r, Decl(variadicTuples1.ts, 151, 50)) + + m = t; +>m : Symbol(m, Decl(variadicTuples1.ts, 151, 39)) +>t : Symbol(t, Decl(variadicTuples1.ts, 151, 34)) + + m = r; // Error +>m : Symbol(m, Decl(variadicTuples1.ts, 151, 39)) +>r : Symbol(r, Decl(variadicTuples1.ts, 151, 50)) + + r = t; +>r : Symbol(r, Decl(variadicTuples1.ts, 151, 50)) +>t : Symbol(t, Decl(variadicTuples1.ts, 151, 34)) + + r = m; +>r : Symbol(r, Decl(variadicTuples1.ts, 151, 50)) +>m : Symbol(m, Decl(variadicTuples1.ts, 151, 39)) +} + +function f12(t: T, m: [...T], r: readonly [...T]) { +>f12 : Symbol(f12, Decl(variadicTuples1.ts, 158, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 160, 13)) +>t : Symbol(t, Decl(variadicTuples1.ts, 160, 43)) +>T : Symbol(T, Decl(variadicTuples1.ts, 160, 13)) +>m : Symbol(m, Decl(variadicTuples1.ts, 160, 48)) +>T : Symbol(T, Decl(variadicTuples1.ts, 160, 13)) +>r : Symbol(r, Decl(variadicTuples1.ts, 160, 59)) +>T : Symbol(T, Decl(variadicTuples1.ts, 160, 13)) + + t = m; +>t : Symbol(t, Decl(variadicTuples1.ts, 160, 43)) +>m : Symbol(m, Decl(variadicTuples1.ts, 160, 48)) + + t = r; // Error +>t : Symbol(t, Decl(variadicTuples1.ts, 160, 43)) +>r : Symbol(r, Decl(variadicTuples1.ts, 160, 59)) + + m = t; // Error +>m : Symbol(m, Decl(variadicTuples1.ts, 160, 48)) +>t : Symbol(t, Decl(variadicTuples1.ts, 160, 43)) + + m = r; // Error +>m : Symbol(m, Decl(variadicTuples1.ts, 160, 48)) +>r : Symbol(r, Decl(variadicTuples1.ts, 160, 59)) + + r = t; +>r : Symbol(r, Decl(variadicTuples1.ts, 160, 59)) +>t : Symbol(t, Decl(variadicTuples1.ts, 160, 43)) + + r = m; +>r : Symbol(r, Decl(variadicTuples1.ts, 160, 59)) +>m : Symbol(m, Decl(variadicTuples1.ts, 160, 48)) +} + +// Inference between variadic tuple types + +type First = T[0]; +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 171, 11)) +>T : Symbol(T, Decl(variadicTuples1.ts, 171, 11)) + +type DropFirst = T extends readonly [any, ...infer U] ? U : [...T]; +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) +>T : Symbol(T, Decl(variadicTuples1.ts, 172, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 172, 15)) +>U : Symbol(U, Decl(variadicTuples1.ts, 172, 80)) +>U : Symbol(U, Decl(variadicTuples1.ts, 172, 80)) +>T : Symbol(T, Decl(variadicTuples1.ts, 172, 15)) + +type Last = T extends readonly [...infer _, infer U] ? U : undefined; +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) +>T : Symbol(T, Decl(variadicTuples1.ts, 174, 10)) +>T : Symbol(T, Decl(variadicTuples1.ts, 174, 10)) +>_ : Symbol(_, Decl(variadicTuples1.ts, 174, 70)) +>U : Symbol(U, Decl(variadicTuples1.ts, 174, 79)) +>U : Symbol(U, Decl(variadicTuples1.ts, 174, 79)) + +type DropLast = T extends readonly [...infer U, any] ? U : [...T]; +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) +>T : Symbol(T, Decl(variadicTuples1.ts, 175, 14)) +>T : Symbol(T, Decl(variadicTuples1.ts, 175, 14)) +>U : Symbol(U, Decl(variadicTuples1.ts, 175, 74)) +>U : Symbol(U, Decl(variadicTuples1.ts, 175, 74)) +>T : Symbol(T, Decl(variadicTuples1.ts, 175, 14)) + +type T00 = First<[number, symbol, string]>; +>T00 : Symbol(T00, Decl(variadicTuples1.ts, 175, 96)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T01 = First<[symbol, string]>; +>T01 : Symbol(T01, Decl(variadicTuples1.ts, 177, 43)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T02 = First<[string]>; +>T02 : Symbol(T02, Decl(variadicTuples1.ts, 178, 35)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T03 = First<[number, symbol, ...string[]]>; +>T03 : Symbol(T03, Decl(variadicTuples1.ts, 179, 27)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T04 = First<[symbol, ...string[]]>; +>T04 : Symbol(T04, Decl(variadicTuples1.ts, 180, 48)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T05 = First; +>T05 : Symbol(T05, Decl(variadicTuples1.ts, 181, 40)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T06 = First<[]>; +>T06 : Symbol(T06, Decl(variadicTuples1.ts, 182, 27)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T07 = First; +>T07 : Symbol(T07, Decl(variadicTuples1.ts, 183, 21)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T08 = First; +>T08 : Symbol(T08, Decl(variadicTuples1.ts, 184, 22)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type T10 = DropFirst<[number, symbol, string]>; +>T10 : Symbol(T10, Decl(variadicTuples1.ts, 185, 24)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T11 = DropFirst<[symbol, string]>; +>T11 : Symbol(T11, Decl(variadicTuples1.ts, 187, 47)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T12 = DropFirst<[string]>; +>T12 : Symbol(T12, Decl(variadicTuples1.ts, 188, 39)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T13 = DropFirst<[number, symbol, ...string[]]>; +>T13 : Symbol(T13, Decl(variadicTuples1.ts, 189, 31)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T14 = DropFirst<[symbol, ...string[]]>; +>T14 : Symbol(T14, Decl(variadicTuples1.ts, 190, 52)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T15 = DropFirst; +>T15 : Symbol(T15, Decl(variadicTuples1.ts, 191, 44)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T16 = DropFirst<[]>; +>T16 : Symbol(T16, Decl(variadicTuples1.ts, 192, 31)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T17 = DropFirst; +>T17 : Symbol(T17, Decl(variadicTuples1.ts, 193, 25)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T18 = DropFirst; +>T18 : Symbol(T18, Decl(variadicTuples1.ts, 194, 26)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type T20 = Last<[number, symbol, string]>; +>T20 : Symbol(T20, Decl(variadicTuples1.ts, 195, 28)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T21 = Last<[symbol, string]>; +>T21 : Symbol(T21, Decl(variadicTuples1.ts, 197, 42)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T22 = Last<[string]>; +>T22 : Symbol(T22, Decl(variadicTuples1.ts, 198, 34)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T23 = Last<[number, symbol, ...string[]]>; +>T23 : Symbol(T23, Decl(variadicTuples1.ts, 199, 26)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T24 = Last<[symbol, ...string[]]>; +>T24 : Symbol(T24, Decl(variadicTuples1.ts, 200, 47)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T25 = Last; +>T25 : Symbol(T25, Decl(variadicTuples1.ts, 201, 39)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T26 = Last<[]>; // unknown[], maybe should be [] +>T26 : Symbol(T26, Decl(variadicTuples1.ts, 202, 26)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T27 = Last; // unknown, maybe should be any +>T27 : Symbol(T27, Decl(variadicTuples1.ts, 203, 20)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T28 = Last; +>T28 : Symbol(T28, Decl(variadicTuples1.ts, 204, 21)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type T30 = DropLast<[number, symbol, string]>; +>T30 : Symbol(T30, Decl(variadicTuples1.ts, 205, 23)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T31 = DropLast<[symbol, string]>; +>T31 : Symbol(T31, Decl(variadicTuples1.ts, 207, 46)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T32 = DropLast<[string]>; +>T32 : Symbol(T32, Decl(variadicTuples1.ts, 208, 38)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T33 = DropLast<[number, symbol, ...string[]]>; +>T33 : Symbol(T33, Decl(variadicTuples1.ts, 209, 30)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T34 = DropLast<[symbol, ...string[]]>; +>T34 : Symbol(T34, Decl(variadicTuples1.ts, 210, 51)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T35 = DropLast; +>T35 : Symbol(T35, Decl(variadicTuples1.ts, 211, 43)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T36 = DropLast<[]>; // unknown[], maybe should be [] +>T36 : Symbol(T36, Decl(variadicTuples1.ts, 212, 30)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T37 = DropLast; +>T37 : Symbol(T37, Decl(variadicTuples1.ts, 213, 24)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type T38 = DropLast; +>T38 : Symbol(T38, Decl(variadicTuples1.ts, 214, 25)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R00 = First; +>R00 : Symbol(R00, Decl(variadicTuples1.ts, 215, 27)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R01 = First; +>R01 : Symbol(R01, Decl(variadicTuples1.ts, 217, 52)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R02 = First; +>R02 : Symbol(R02, Decl(variadicTuples1.ts, 218, 44)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R03 = First; +>R03 : Symbol(R03, Decl(variadicTuples1.ts, 219, 36)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R04 = First; +>R04 : Symbol(R04, Decl(variadicTuples1.ts, 220, 57)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R05 = First; +>R05 : Symbol(R05, Decl(variadicTuples1.ts, 221, 49)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R06 = First; +>R06 : Symbol(R06, Decl(variadicTuples1.ts, 222, 36)) +>First : Symbol(First, Decl(variadicTuples1.ts, 167, 1)) + +type R10 = DropFirst; +>R10 : Symbol(R10, Decl(variadicTuples1.ts, 223, 30)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R11 = DropFirst; +>R11 : Symbol(R11, Decl(variadicTuples1.ts, 225, 56)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R12 = DropFirst; +>R12 : Symbol(R12, Decl(variadicTuples1.ts, 226, 48)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R13 = DropFirst; +>R13 : Symbol(R13, Decl(variadicTuples1.ts, 227, 40)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R14 = DropFirst; +>R14 : Symbol(R14, Decl(variadicTuples1.ts, 228, 61)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R15 = DropFirst; +>R15 : Symbol(R15, Decl(variadicTuples1.ts, 229, 53)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R16 = DropFirst; +>R16 : Symbol(R16, Decl(variadicTuples1.ts, 230, 40)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 171, 48)) + +type R20 = Last; +>R20 : Symbol(R20, Decl(variadicTuples1.ts, 231, 34)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R21 = Last; +>R21 : Symbol(R21, Decl(variadicTuples1.ts, 233, 51)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R22 = Last; +>R22 : Symbol(R22, Decl(variadicTuples1.ts, 234, 43)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R23 = Last; +>R23 : Symbol(R23, Decl(variadicTuples1.ts, 235, 35)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R24 = Last; +>R24 : Symbol(R24, Decl(variadicTuples1.ts, 236, 56)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R25 = Last; +>R25 : Symbol(R25, Decl(variadicTuples1.ts, 237, 48)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R26 = Last; +>R26 : Symbol(R26, Decl(variadicTuples1.ts, 238, 35)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 172, 97)) + +type R30 = DropLast; +>R30 : Symbol(R30, Decl(variadicTuples1.ts, 239, 29)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R31 = DropLast; +>R31 : Symbol(R31, Decl(variadicTuples1.ts, 241, 55)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R32 = DropLast; +>R32 : Symbol(R32, Decl(variadicTuples1.ts, 242, 47)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R33 = DropLast; +>R33 : Symbol(R33, Decl(variadicTuples1.ts, 243, 39)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R34 = DropLast; +>R34 : Symbol(R34, Decl(variadicTuples1.ts, 244, 60)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R35 = DropLast; +>R35 : Symbol(R35, Decl(variadicTuples1.ts, 245, 52)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +type R36 = DropLast; +>R36 : Symbol(R36, Decl(variadicTuples1.ts, 246, 39)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 174, 99)) + +// Inference to [...T, ...U] with implied arity for T + +function curry(f: (...args: [...T, ...U]) => R, ...a: T) { +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>T : Symbol(T, Decl(variadicTuples1.ts, 251, 15)) +>U : Symbol(U, Decl(variadicTuples1.ts, 251, 35)) +>R : Symbol(R, Decl(variadicTuples1.ts, 251, 56)) +>f : Symbol(f, Decl(variadicTuples1.ts, 251, 60)) +>args : Symbol(args, Decl(variadicTuples1.ts, 251, 64)) +>T : Symbol(T, Decl(variadicTuples1.ts, 251, 15)) +>U : Symbol(U, Decl(variadicTuples1.ts, 251, 35)) +>R : Symbol(R, Decl(variadicTuples1.ts, 251, 56)) +>a : Symbol(a, Decl(variadicTuples1.ts, 251, 92)) +>T : Symbol(T, Decl(variadicTuples1.ts, 251, 15)) + + return (...b: U) => f(...a, ...b); +>b : Symbol(b, Decl(variadicTuples1.ts, 252, 12)) +>U : Symbol(U, Decl(variadicTuples1.ts, 251, 35)) +>f : Symbol(f, Decl(variadicTuples1.ts, 251, 60)) +>a : Symbol(a, Decl(variadicTuples1.ts, 251, 92)) +>b : Symbol(b, Decl(variadicTuples1.ts, 252, 12)) +} + +const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 255, 5)) +>a : Symbol(a, Decl(variadicTuples1.ts, 255, 13)) +>b : Symbol(b, Decl(variadicTuples1.ts, 255, 23)) +>c : Symbol(c, Decl(variadicTuples1.ts, 255, 34)) +>d : Symbol(d, Decl(variadicTuples1.ts, 255, 46)) + +const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number +>c0 : Symbol(c0, Decl(variadicTuples1.ts, 257, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 255, 5)) + +const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number +>c1 : Symbol(c1, Decl(variadicTuples1.ts, 258, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 255, 5)) + +const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number +>c2 : Symbol(c2, Decl(variadicTuples1.ts, 259, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 255, 5)) + +const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number +>c3 : Symbol(c3, Decl(variadicTuples1.ts, 260, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 255, 5)) + +const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number +>c4 : Symbol(c4, Decl(variadicTuples1.ts, 261, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 255, 5)) + +const fn2 = (x: number, b: boolean, ...args: string[]) => 0; +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 263, 5)) +>x : Symbol(x, Decl(variadicTuples1.ts, 263, 13)) +>b : Symbol(b, Decl(variadicTuples1.ts, 263, 23)) +>args : Symbol(args, Decl(variadicTuples1.ts, 263, 35)) + +const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number +>c10 : Symbol(c10, Decl(variadicTuples1.ts, 265, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 263, 5)) + +const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number +>c11 : Symbol(c11, Decl(variadicTuples1.ts, 266, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 263, 5)) + +const c12 = curry(fn2, 1, true); // (...args: string[]) => number +>c12 : Symbol(c12, Decl(variadicTuples1.ts, 267, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 263, 5)) + +const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number +>c13 : Symbol(c13, Decl(variadicTuples1.ts, 268, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 263, 5)) + +const fn3 = (...args: string[]) => 0; +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 270, 5)) +>args : Symbol(args, Decl(variadicTuples1.ts, 270, 13)) + +const c20 = curry(fn3); // (...args: string[]) => number +>c20 : Symbol(c20, Decl(variadicTuples1.ts, 272, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 270, 5)) + +const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number +>c21 : Symbol(c21, Decl(variadicTuples1.ts, 273, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 270, 5)) + +const c22 = curry(fn3, ...sa); // (...args: string[]) => number +>c22 : Symbol(c22, Decl(variadicTuples1.ts, 274, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 247, 33)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 270, 5)) +>sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) + +// No inference to [...T, ...U] when there is no implied arity + +function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]) { +>curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 274, 30)) +>T : Symbol(T, Decl(variadicTuples1.ts, 278, 16)) +>U : Symbol(U, Decl(variadicTuples1.ts, 278, 36)) +>R : Symbol(R, Decl(variadicTuples1.ts, 278, 57)) +>f : Symbol(f, Decl(variadicTuples1.ts, 278, 61)) +>args : Symbol(args, Decl(variadicTuples1.ts, 278, 65)) +>T : Symbol(T, Decl(variadicTuples1.ts, 278, 16)) +>U : Symbol(U, Decl(variadicTuples1.ts, 278, 36)) +>R : Symbol(R, Decl(variadicTuples1.ts, 278, 57)) +>t : Symbol(t, Decl(variadicTuples1.ts, 278, 93)) +>T : Symbol(T, Decl(variadicTuples1.ts, 278, 16)) +>u : Symbol(u, Decl(variadicTuples1.ts, 278, 104)) +>U : Symbol(U, Decl(variadicTuples1.ts, 278, 36)) + + return f(...t, ...u); +>f : Symbol(f, Decl(variadicTuples1.ts, 278, 61)) +>t : Symbol(t, Decl(variadicTuples1.ts, 278, 93)) +>u : Symbol(u, Decl(variadicTuples1.ts, 278, 104)) +} + +declare function fn10(a: string, b: number, c: boolean): string[]; +>fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 280, 1)) +>a : Symbol(a, Decl(variadicTuples1.ts, 282, 22)) +>b : Symbol(b, Decl(variadicTuples1.ts, 282, 32)) +>c : Symbol(c, Decl(variadicTuples1.ts, 282, 43)) + +curry2(fn10, ['hello', 42], [true]); +>curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 274, 30)) +>fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 280, 1)) + +curry2(fn10, ['hello'], [42, true]); +>curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 274, 30)) +>fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 280, 1)) + +// Last argument is contextually typed + +declare function call(...args: [...T, (...args: T) => R]): [T, R]; +>call : Symbol(call, Decl(variadicTuples1.ts, 285, 36)) +>T : Symbol(T, Decl(variadicTuples1.ts, 289, 22)) +>R : Symbol(R, Decl(variadicTuples1.ts, 289, 42)) +>args : Symbol(args, Decl(variadicTuples1.ts, 289, 46)) +>T : Symbol(T, Decl(variadicTuples1.ts, 289, 22)) +>args : Symbol(args, Decl(variadicTuples1.ts, 289, 63)) +>T : Symbol(T, Decl(variadicTuples1.ts, 289, 22)) +>R : Symbol(R, Decl(variadicTuples1.ts, 289, 42)) +>T : Symbol(T, Decl(variadicTuples1.ts, 289, 22)) +>R : Symbol(R, Decl(variadicTuples1.ts, 289, 42)) + +call('hello', 32, (a, b) => 42); +>call : Symbol(call, Decl(variadicTuples1.ts, 285, 36)) +>a : Symbol(a, Decl(variadicTuples1.ts, 291, 19)) +>b : Symbol(b, Decl(variadicTuples1.ts, 291, 21)) + +// Would be nice to infer [...string[], (...args: string[]) => number] here +// Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure + +call(...sa, (...x) => 42); +>call : Symbol(call, Decl(variadicTuples1.ts, 285, 36)) +>sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) +>x : Symbol(x, Decl(variadicTuples1.ts, 296, 13)) + diff --git a/tests/baselines/reference/variadicTuples1.types b/tests/baselines/reference/variadicTuples1.types new file mode 100644 index 0000000000000..616127e76172c --- /dev/null +++ b/tests/baselines/reference/variadicTuples1.types @@ -0,0 +1,1033 @@ +=== tests/cases/conformance/types/tuple/variadicTuples1.ts === +// Variadics in tuple types + +type TV0 = [string, ...T]; +>TV0 : [string, ...T] + +type TV1 = [string, ...T, number]; +>TV1 : [string, ...T, number] + +type TV2 = [string, ...T, number, ...T]; +>TV2 : [string, ...T, number, ...T] + +type TV3 = [string, ...T, ...number[], ...T]; // Error +>TV3 : [string, ...T, ...number[], ...T] + +// Normalization + +type TN1 = TV1<[boolean, string]>; +>TN1 : [string, boolean, string, number] + +type TN2 = TV1<[]>; +>TN2 : [string, number] + +type TN3 = TV1<[boolean?]>; +>TN3 : [string, boolean | undefined, number] + +type TN4 = TV1; +>TN4 : [string, ...(string | number)[]] + +type TN5 = TV1<[boolean] | [symbol, symbol]>; +>TN5 : [string, boolean, number] | [string, symbol, symbol, number] + +type TN6 = TV1; +>TN6 : [string, ...any[]] + +type TN7 = TV1; +>TN7 : never + +// Variadics in array literals + +function tup2(t: [...T], u: [...U]) { +>tup2 : (t: [...T], u: [...U]) => readonly [1, ...T, 2, ...U, 3] +>t : [...T] +>u : [...U] + + return [1, ...t, 2, ...u, 3] as const; +>[1, ...t, 2, ...u, 3] as const : readonly [1, ...T, 2, ...U, 3] +>[1, ...t, 2, ...u, 3] : readonly [1, ...T, 2, ...U, 3] +>1 : 1 +>...t : T[number] +>t : [...T] +>2 : 2 +>...u : U[number] +>u : [...U] +>3 : 3 +} + +const t2 = tup2(['hello'], [10, true]); +>t2 : readonly [1, string, 2, number, boolean, 3] +>tup2(['hello'], [10, true]) : readonly [1, string, 2, number, boolean, 3] +>tup2 : (t: [...T], u: [...U]) => readonly [1, ...T, 2, ...U, 3] +>['hello'] : [string] +>'hello' : "hello" +>[10, true] : [number, true] +>10 : 10 +>true : true + +function concat(t: [...T], u: [...U]): [...T, ...U] { +>concat : (t: [...T], u: [...U]) => [...T, ...U] +>t : [...T] +>u : [...U] + + return [...t, ...u]; +>[...t, ...u] : [...T, ...U] +>...t : T[number] +>t : [...T] +>...u : U[number] +>u : [...U] +} + +declare const sa: string[]; +>sa : string[] + +const tc1 = concat([], []); +>tc1 : [] +>concat([], []) : [] +>concat : (t: [...T], u: [...U]) => [...T, ...U] +>[] : [] +>[] : [] + +const tc2 = concat(['hello'], [42]); +>tc2 : [string, number] +>concat(['hello'], [42]) : [string, number] +>concat : (t: [...T], u: [...U]) => [...T, ...U] +>['hello'] : [string] +>'hello' : "hello" +>[42] : [number] +>42 : 42 + +const tc3 = concat([1, 2, 3], sa); +>tc3 : [number, number, number, ...string[]] +>concat([1, 2, 3], sa) : [number, number, number, ...string[]] +>concat : (t: [...T], u: [...U]) => [...T, ...U] +>[1, 2, 3] : [number, number, number] +>1 : 1 +>2 : 2 +>3 : 3 +>sa : string[] + +const tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] +>tc4 : (string | number)[] +>concat(sa, [1, 2, 3]) : (string | number)[] +>concat : (t: [...T], u: [...U]) => [...T, ...U] +>sa : string[] +>[1, 2, 3] : [number, number, number] +>1 : 1 +>2 : 2 +>3 : 3 + +// Spread arguments + +declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>a : number +>b : string +>c : boolean +>d : number[] + +function foo2(t1: [number, string], t2: [boolean], a1: number[]) { +>foo2 : (t1: [number, string], t2: [boolean], a1: number[]) => void +>t1 : [number, string] +>t2 : [boolean] +>a1 : number[] + + foo1(1, 'abc', true, 42, 43, 44); +>foo1(1, 'abc', true, 42, 43, 44) : void +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>1 : 1 +>'abc' : "abc" +>true : true +>42 : 42 +>43 : 43 +>44 : 44 + + foo1(...t1, true, 42, 43, 44); +>foo1(...t1, true, 42, 43, 44) : void +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>...t1 : string | number +>t1 : [number, string] +>true : true +>42 : 42 +>43 : 43 +>44 : 44 + + foo1(...t1, ...t2, 42, 43, 44); +>foo1(...t1, ...t2, 42, 43, 44) : void +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>...t1 : string | number +>t1 : [number, string] +>...t2 : boolean +>t2 : [boolean] +>42 : 42 +>43 : 43 +>44 : 44 + + foo1(...t1, ...t2, ...a1); +>foo1(...t1, ...t2, ...a1) : void +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>...t1 : string | number +>t1 : [number, string] +>...t2 : boolean +>t2 : [boolean] +>...a1 : number +>a1 : number[] + + foo1(...t1); // Error +>foo1(...t1) : void +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>...t1 : string | number +>t1 : [number, string] + + foo1(...t1, 45); // Error +>foo1(...t1, 45) : void +>foo1 : (a: number, b: string, c: boolean, ...d: number[]) => void +>...t1 : string | number +>t1 : [number, string] +>45 : 45 +} + +declare function foo3(x: number, ...args: [...T, number]): T; +>foo3 : (x: number, ...args_0: T, args_1: number) => T +>x : number +>args : [...T, number] + +function foo4(u: U) { +>foo4 : (u: U) => void +>u : U + + foo3(1, 2); +>foo3(1, 2) : [] +>foo3 : (x: number, ...args_0: T, args_1: number) => T +>1 : 1 +>2 : 2 + + foo3(1, 'hello', true, 2); +>foo3(1, 'hello', true, 2) : [string, boolean] +>foo3 : (x: number, ...args_0: T, args_1: number) => T +>1 : 1 +>'hello' : "hello" +>true : true +>2 : 2 + + foo3(1, ...u, 'hi', 2); +>foo3(1, ...u, 'hi', 2) : [...U, string] +>foo3 : (x: number, ...args_0: T, args_1: number) => T +>1 : 1 +>...u : unknown +>u : U +>'hi' : "hi" +>2 : 2 + + foo3(1); +>foo3(1) : unknown[] +>foo3 : (x: number, ...args_0: T, args_1: number) => T +>1 : 1 +} + +// Contextual typing of array literals + +declare function ft1(t: T): T; +>ft1 : (t: T) => T +>t : T + +declare function ft2(t: T): readonly [...T]; +>ft2 : (t: T) => readonly [...T] +>t : T + +declare function ft3(t: [...T]): T; +>ft3 : (t: [...T]) => T +>t : [...T] + +declare function ft4(t: [...T]): readonly [...T]; +>ft4 : (t: [...T]) => readonly [...T] +>t : [...T] + +ft1(['hello', 42]); // (string | number)[] +>ft1(['hello', 42]) : (string | number)[] +>ft1 : (t: T) => T +>['hello', 42] : (string | number)[] +>'hello' : "hello" +>42 : 42 + +ft2(['hello', 42]); // readonly (string | number)[] +>ft2(['hello', 42]) : readonly (string | number)[] +>ft2 : (t: T) => readonly [...T] +>['hello', 42] : (string | number)[] +>'hello' : "hello" +>42 : 42 + +ft3(['hello', 42]); // [string, number] +>ft3(['hello', 42]) : [string, number] +>ft3 : (t: [...T]) => T +>['hello', 42] : [string, number] +>'hello' : "hello" +>42 : 42 + +ft4(['hello', 42]); // readonly [string, number] +>ft4(['hello', 42]) : readonly [string, number] +>ft4 : (t: [...T]) => readonly [...T] +>['hello', 42] : [string, number] +>'hello' : "hello" +>42 : 42 + +// Indexing variadic tuple types + +function f0(t: [string, ...T], n: number) { +>f0 : (t: [string, ...T], n: number) => void +>t : [string, ...T] +>n : number + + const a = t[0]; // string +>a : string +>t[0] : string +>t : [string, ...T] +>0 : 0 + + const b = t[1]; // [string, ...T][1] +>b : [string, ...T][1] +>t[1] : [string, ...T][1] +>t : [string, ...T] +>1 : 1 + + const c = t[2]; // [string, ...T][2] +>c : [string, ...T][2] +>t[2] : [string, ...T][2] +>t : [string, ...T] +>2 : 2 + + const d = t[n]; // [string, ...T][number] +>d : [string, ...T][number] +>t[n] : [string, ...T][number] +>t : [string, ...T] +>n : number +} + +function f1(t: [string, ...T, number], n: number) { +>f1 : (t: [string, ...T, number], n: number) => void +>t : [string, ...T, number] +>n : number + + const a = t[0]; // string +>a : string +>t[0] : string +>t : [string, ...T, number] +>0 : 0 + + const b = t[1]; // [string, ...T, number][1] +>b : [string, ...T, number][1] +>t[1] : [string, ...T, number][1] +>t : [string, ...T, number] +>1 : 1 + + const c = t[2]; // [string, ...T, number][2] +>c : [string, ...T, number][2] +>t[2] : [string, ...T, number][2] +>t : [string, ...T, number] +>2 : 2 + + const d = t[n]; // [string, ...T, number][number] +>d : [string, ...T, number][number] +>t[n] : [string, ...T, number][number] +>t : [string, ...T, number] +>n : number +} + +// Destructuring variadic tuple types + +function f2(t: [string, ...T]) { +>f2 : (t: [string, ...T]) => void +>t : [string, ...T] + + let [...ax] = t; // [string, ...T] +>ax : [string, ...T] +>t : [string, ...T] + + let [b1, ...bx] = t; // string, [...T] +>b1 : string +>bx : [...T] +>t : [string, ...T] + + let [c1, c2, ...cx] = t; // string, [string, ...T][1], T[number][] +>c1 : string +>c2 : [string, ...T][1] +>cx : T[number][] +>t : [string, ...T] +} + +function f3(t: [string, ...T, number]) { +>f3 : (t: [string, ...T, number]) => void +>t : [string, ...T, number] + + let [...ax] = t; // [string, ...T, number] +>ax : [string, ...T, number] +>t : [string, ...T, number] + + let [b1, ...bx] = t; // string, [...T, number] +>b1 : string +>bx : [...T, number] +>t : [string, ...T, number] + + let [c1, c2, ...cx] = t; // string, [string, ...T, number][1], (number | T[number])[] +>c1 : string +>c2 : [string, ...T, number][1] +>cx : (number | T[number])[] +>t : [string, ...T, number] +} + +// Mapped types applied to variadic tuple types + +type Arrayify = { [P in keyof T]: T[P][] }; +>Arrayify : Arrayify + +type TM1 = Arrayify; // [string[], (number | undefined)[]?, Arrayify, ...boolean[][]] +>TM1 : readonly [string[], (number | undefined)[]?, ...Arrayify, ...boolean[][]] + +type TP1 = Partial<[string, ...T, number]>; // [string?, Partial, number?] +>TP1 : [(string | undefined)?, ...Partial, (number | undefined)?] + +type TP2 = Partial<[string, ...T, ...number[]]>; // [string?, Partial, ...(number | undefined)[]] +>TP2 : [(string | undefined)?, ...Partial, ...(number | undefined)[]] + +// Reverse mapping through mapped type applied to variadic tuple type + +declare function fm1(t: Arrayify<[string, number, ...T]>): T; +>fm1 : (t: [string[], number[], ...Arrayify]) => T +>t : [string[], number[], ...Arrayify] + +let tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] +>tm1 : [boolean, string] +>fm1([['abc'], [42], [true], ['def']]) : [boolean, string] +>fm1 : (t: [string[], number[], ...Arrayify]) => T +>[['abc'], [42], [true], ['def']] : [string[], number[], true[], string[]] +>['abc'] : string[] +>'abc' : "abc" +>[42] : number[] +>42 : 42 +>[true] : true[] +>true : true +>['def'] : string[] +>'def' : "def" + +// Spread of readonly array-like infers mutable array-like + +declare function fx1(a: string, ...args: T): T; +>fx1 : (a: string, ...args: T) => T +>a : string +>args : T + +function gx1(u: U, v: V) { +>gx1 : (u: U, v: V) => void +>u : U +>v : V + + fx1('abc'); // [] +>fx1('abc') : [] +>fx1 : (a: string, ...args: T) => T +>'abc' : "abc" + + fx1('abc', ...u); // U +>fx1('abc', ...u) : U +>fx1 : (a: string, ...args: T) => T +>'abc' : "abc" +>...u : unknown +>u : U + + fx1('abc', ...v); // [...V] +>fx1('abc', ...v) : [...V] +>fx1 : (a: string, ...args: T) => T +>'abc' : "abc" +>...v : unknown +>v : V + + fx1('abc', ...u); // U +>fx1('abc', ...u) : U +>fx1 : (a: string, ...args: T) => T +>'abc' : "abc" +>...u : unknown +>u : U + + fx1('abc', ...v); // Error +>fx1('abc', ...v) : V +>fx1 : (a: string, ...args: T) => T +>'abc' : "abc" +>...v : unknown +>v : V +} + +declare function fx2(a: string, ...args: T): T; +>fx2 : (a: string, ...args: T) => T +>a : string +>args : T + +function gx2(u: U, v: V) { +>gx2 : (u: U, v: V) => void +>u : U +>v : V + + fx2('abc'); // [] +>fx2('abc') : [] +>fx2 : (a: string, ...args: T) => T +>'abc' : "abc" + + fx2('abc', ...u); // U +>fx2('abc', ...u) : U +>fx2 : (a: string, ...args: T) => T +>'abc' : "abc" +>...u : unknown +>u : U + + fx2('abc', ...v); // [...V] +>fx2('abc', ...v) : [...V] +>fx2 : (a: string, ...args: T) => T +>'abc' : "abc" +>...v : unknown +>v : V + + fx2('abc', ...u); // U +>fx2('abc', ...u) : U +>fx2 : (a: string, ...args: T) => T +>'abc' : "abc" +>...u : unknown +>u : U + + fx2('abc', ...v); // V +>fx2('abc', ...v) : V +>fx2 : (a: string, ...args: T) => T +>'abc' : "abc" +>...v : unknown +>v : V +} + +// Relations involving variadic tuple types + +function f10(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) { +>f10 : (x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) => void +>x : [string, ...unknown[]] +>y : [string, ...T] +>z : [string, ...U] + + x = y; +>x = y : [string, ...T] +>x : [string, ...unknown[]] +>y : [string, ...T] + + x = z; +>x = z : [string, ...U] +>x : [string, ...unknown[]] +>z : [string, ...U] + + y = x; // Error +>y = x : [string, ...unknown[]] +>y : [string, ...T] +>x : [string, ...unknown[]] + + y = z; +>y = z : [string, ...U] +>y : [string, ...T] +>z : [string, ...U] + + z = x; // Error +>z = x : [string, ...unknown[]] +>z : [string, ...U] +>x : [string, ...unknown[]] + + z = y; // Error +>z = y : [string, ...T] +>z : [string, ...U] +>y : [string, ...T] +} + +// For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable +// to [...T] when T is constrained to a mutable array or tuple type. + +function f11(t: T, m: [...T], r: readonly [...T]) { +>f11 : (t: T, m: [...T], r: readonly [...T]) => void +>t : T +>m : [...T] +>r : readonly [...T] + + t = m; +>t = m : [...T] +>t : T +>m : [...T] + + t = r; // Error +>t = r : readonly [...T] +>t : T +>r : readonly [...T] + + m = t; +>m = t : T +>m : [...T] +>t : T + + m = r; // Error +>m = r : readonly [...T] +>m : [...T] +>r : readonly [...T] + + r = t; +>r = t : T +>r : readonly [...T] +>t : T + + r = m; +>r = m : [...T] +>r : readonly [...T] +>m : [...T] +} + +function f12(t: T, m: [...T], r: readonly [...T]) { +>f12 : (t: T, m: [...T], r: readonly [...T]) => void +>t : T +>m : [...T] +>r : readonly [...T] + + t = m; +>t = m : [...T] +>t : T +>m : [...T] + + t = r; // Error +>t = r : readonly [...T] +>t : T +>r : readonly [...T] + + m = t; // Error +>m = t : T +>m : [...T] +>t : T + + m = r; // Error +>m = r : readonly [...T] +>m : [...T] +>r : readonly [...T] + + r = t; +>r = t : T +>r : readonly [...T] +>t : T + + r = m; +>r = m : [...T] +>r : readonly [...T] +>m : [...T] +} + +// Inference between variadic tuple types + +type First = T[0]; +>First : First + +type DropFirst = T extends readonly [any, ...infer U] ? U : [...T]; +>DropFirst : DropFirst + +type Last = T extends readonly [...infer _, infer U] ? U : undefined; +>Last : Last + +type DropLast = T extends readonly [...infer U, any] ? U : [...T]; +>DropLast : DropLast + +type T00 = First<[number, symbol, string]>; +>T00 : number + +type T01 = First<[symbol, string]>; +>T01 : symbol + +type T02 = First<[string]>; +>T02 : string + +type T03 = First<[number, symbol, ...string[]]>; +>T03 : number + +type T04 = First<[symbol, ...string[]]>; +>T04 : symbol + +type T05 = First; +>T05 : string + +type T06 = First<[]>; +>T06 : undefined + +type T07 = First; +>T07 : any + +type T08 = First; +>T08 : never + +type T10 = DropFirst<[number, symbol, string]>; +>T10 : [symbol, string] + +type T11 = DropFirst<[symbol, string]>; +>T11 : [string] + +type T12 = DropFirst<[string]>; +>T12 : [] + +type T13 = DropFirst<[number, symbol, ...string[]]>; +>T13 : [symbol, ...string[]] + +type T14 = DropFirst<[symbol, ...string[]]>; +>T14 : string[] + +type T15 = DropFirst; +>T15 : string[] + +type T16 = DropFirst<[]>; +>T16 : [] + +type T17 = DropFirst; +>T17 : unknown[] | any[] + +type T18 = DropFirst; +>T18 : never + +type T20 = Last<[number, symbol, string]>; +>T20 : string + +type T21 = Last<[symbol, string]>; +>T21 : string + +type T22 = Last<[string]>; +>T22 : string + +type T23 = Last<[number, symbol, ...string[]]>; +>T23 : string + +type T24 = Last<[symbol, ...string[]]>; +>T24 : string + +type T25 = Last; +>T25 : string + +type T26 = Last<[]>; // unknown[], maybe should be [] +>T26 : unknown + +type T27 = Last; // unknown, maybe should be any +>T27 : unknown + +type T28 = Last; +>T28 : never + +type T30 = DropLast<[number, symbol, string]>; +>T30 : [number, symbol] + +type T31 = DropLast<[symbol, string]>; +>T31 : [symbol] + +type T32 = DropLast<[string]>; +>T32 : [] + +type T33 = DropLast<[number, symbol, ...string[]]>; +>T33 : [number, symbol, ...string[]] + +type T34 = DropLast<[symbol, ...string[]]>; +>T34 : [symbol, ...string[]] + +type T35 = DropLast; +>T35 : string[] + +type T36 = DropLast<[]>; // unknown[], maybe should be [] +>T36 : unknown[] + +type T37 = DropLast; +>T37 : unknown[] | any[] + +type T38 = DropLast; +>T38 : never + +type R00 = First; +>R00 : number + +type R01 = First; +>R01 : symbol + +type R02 = First; +>R02 : string + +type R03 = First; +>R03 : number + +type R04 = First; +>R04 : symbol + +type R05 = First; +>R05 : string + +type R06 = First; +>R06 : undefined + +type R10 = DropFirst; +>R10 : [symbol, string] + +type R11 = DropFirst; +>R11 : [string] + +type R12 = DropFirst; +>R12 : [] + +type R13 = DropFirst; +>R13 : [symbol, ...string[]] + +type R14 = DropFirst; +>R14 : string[] + +type R15 = DropFirst; +>R15 : string[] + +type R16 = DropFirst; +>R16 : [] + +type R20 = Last; +>R20 : string + +type R21 = Last; +>R21 : string + +type R22 = Last; +>R22 : string + +type R23 = Last; +>R23 : string + +type R24 = Last; +>R24 : string + +type R25 = Last; +>R25 : string + +type R26 = Last; +>R26 : unknown + +type R30 = DropLast; +>R30 : [number, symbol] + +type R31 = DropLast; +>R31 : [symbol] + +type R32 = DropLast; +>R32 : [] + +type R33 = DropLast; +>R33 : [number, symbol, ...string[]] + +type R34 = DropLast; +>R34 : [symbol, ...string[]] + +type R35 = DropLast; +>R35 : string[] + +type R36 = DropLast; +>R36 : unknown[] + +// Inference to [...T, ...U] with implied arity for T + +function curry(f: (...args: [...T, ...U]) => R, ...a: T) { +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>f : (...args_0: T, ...args_1: U) => R +>args : [...T, ...U] +>a : T + + return (...b: U) => f(...a, ...b); +>(...b: U) => f(...a, ...b) : (...b: U) => R +>b : U +>f(...a, ...b) : R +>f : (...args_0: T, ...args_1: U) => R +>...a : unknown +>a : T +>...b : unknown +>b : U +} + +const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; +>fn1 : (a: number, b: string, c: boolean, d: string[]) => number +>(a: number, b: string, c: boolean, d: string[]) => 0 : (a: number, b: string, c: boolean, d: string[]) => number +>a : number +>b : string +>c : boolean +>d : string[] +>0 : 0 + +const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number +>c0 : (a: number, b: string, c: boolean, d: string[]) => number +>curry(fn1) : (a: number, b: string, c: boolean, d: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn1 : (a: number, b: string, c: boolean, d: string[]) => number + +const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number +>c1 : (b: string, c: boolean, d: string[]) => number +>curry(fn1, 1) : (b: string, c: boolean, d: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn1 : (a: number, b: string, c: boolean, d: string[]) => number +>1 : 1 + +const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number +>c2 : (c: boolean, d: string[]) => number +>curry(fn1, 1, 'abc') : (c: boolean, d: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn1 : (a: number, b: string, c: boolean, d: string[]) => number +>1 : 1 +>'abc' : "abc" + +const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number +>c3 : (d: string[]) => number +>curry(fn1, 1, 'abc', true) : (d: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn1 : (a: number, b: string, c: boolean, d: string[]) => number +>1 : 1 +>'abc' : "abc" +>true : true + +const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number +>c4 : () => number +>curry(fn1, 1, 'abc', true, ['x', 'y']) : () => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn1 : (a: number, b: string, c: boolean, d: string[]) => number +>1 : 1 +>'abc' : "abc" +>true : true +>['x', 'y'] : string[] +>'x' : "x" +>'y' : "y" + +const fn2 = (x: number, b: boolean, ...args: string[]) => 0; +>fn2 : (x: number, b: boolean, ...args: string[]) => number +>(x: number, b: boolean, ...args: string[]) => 0 : (x: number, b: boolean, ...args: string[]) => number +>x : number +>b : boolean +>args : string[] +>0 : 0 + +const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number +>c10 : (x: number, b: boolean, ...args: string[]) => number +>curry(fn2) : (x: number, b: boolean, ...args: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn2 : (x: number, b: boolean, ...args: string[]) => number + +const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number +>c11 : (b: boolean, ...args: string[]) => number +>curry(fn2, 1) : (b: boolean, ...args: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn2 : (x: number, b: boolean, ...args: string[]) => number +>1 : 1 + +const c12 = curry(fn2, 1, true); // (...args: string[]) => number +>c12 : (...b: string[]) => number +>curry(fn2, 1, true) : (...b: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn2 : (x: number, b: boolean, ...args: string[]) => number +>1 : 1 +>true : true + +const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number +>c13 : (...b: string[]) => number +>curry(fn2, 1, true, 'abc', 'def') : (...b: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn2 : (x: number, b: boolean, ...args: string[]) => number +>1 : 1 +>true : true +>'abc' : "abc" +>'def' : "def" + +const fn3 = (...args: string[]) => 0; +>fn3 : (...args: string[]) => number +>(...args: string[]) => 0 : (...args: string[]) => number +>args : string[] +>0 : 0 + +const c20 = curry(fn3); // (...args: string[]) => number +>c20 : (...b: string[]) => number +>curry(fn3) : (...b: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn3 : (...args: string[]) => number + +const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number +>c21 : (...b: string[]) => number +>curry(fn3, 'abc', 'def') : (...b: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn3 : (...args: string[]) => number +>'abc' : "abc" +>'def' : "def" + +const c22 = curry(fn3, ...sa); // (...args: string[]) => number +>c22 : (...b: string[]) => number +>curry(fn3, ...sa) : (...b: string[]) => number +>curry : (f: (...args_0: T, ...args_1: U) => R, ...a: T) => (...b: U) => R +>fn3 : (...args: string[]) => number +>...sa : string +>sa : string[] + +// No inference to [...T, ...U] when there is no implied arity + +function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]) { +>curry2 : (f: (...args_0: T, ...args_1: U) => R, t: [...T], u: [...U]) => R +>f : (...args_0: T, ...args_1: U) => R +>args : [...T, ...U] +>t : [...T] +>u : [...U] + + return f(...t, ...u); +>f(...t, ...u) : R +>f : (...args_0: T, ...args_1: U) => R +>...t : T[number] +>t : [...T] +>...u : U[number] +>u : [...U] +} + +declare function fn10(a: string, b: number, c: boolean): string[]; +>fn10 : (a: string, b: number, c: boolean) => string[] +>a : string +>b : number +>c : boolean + +curry2(fn10, ['hello', 42], [true]); +>curry2(fn10, ['hello', 42], [true]) : string[] +>curry2 : (f: (...args_0: T, ...args_1: U) => R, t: [...T], u: [...U]) => R +>fn10 : (a: string, b: number, c: boolean) => string[] +>['hello', 42] : [string, number] +>'hello' : "hello" +>42 : 42 +>[true] : [true] +>true : true + +curry2(fn10, ['hello'], [42, true]); +>curry2(fn10, ['hello'], [42, true]) : string[] +>curry2 : (f: (...args_0: T, ...args_1: U) => R, t: [...T], u: [...U]) => R +>fn10 : (a: string, b: number, c: boolean) => string[] +>['hello'] : [string] +>'hello' : "hello" +>[42, true] : [number, true] +>42 : 42 +>true : true + +// Last argument is contextually typed + +declare function call(...args: [...T, (...args: T) => R]): [T, R]; +>call : (...args_0: T, args_1: (...args: T) => R) => [T, R] +>args : [...T, (...args: T) => R] +>args : T + +call('hello', 32, (a, b) => 42); +>call('hello', 32, (a, b) => 42) : [[string, number], number] +>call : (...args_0: T, args_1: (...args: T) => R) => [T, R] +>'hello' : "hello" +>32 : 32 +>(a, b) => 42 : (a: string, b: number) => number +>a : string +>b : number +>42 : 42 + +// Would be nice to infer [...string[], (...args: string[]) => number] here +// Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure + +call(...sa, (...x) => 42); +>call(...sa, (...x) => 42) : [(string | ((...x: any[]) => number))[], number] +>call : (...args_0: T, args_1: (...args: T) => R) => [T, R] +>...sa : string +>sa : string[] +>(...x) => 42 : (...x: any[]) => number +>x : any[] +>42 : 42 + diff --git a/tests/baselines/reference/wideningTuples3.errors.txt b/tests/baselines/reference/wideningTuples3.errors.txt index 15e02cfb5594b..8ff30a555ee7b 100644 --- a/tests/baselines/reference/wideningTuples3.errors.txt +++ b/tests/baselines/reference/wideningTuples3.errors.txt @@ -1,7 +1,6 @@ tests/cases/conformance/types/tuple/wideningTuples3.ts(3,5): error TS7005: Variable 'b' implicitly has an '[any, any]' type. tests/cases/conformance/types/tuple/wideningTuples3.ts(3,9): error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. - Types of property 'length' are incompatible. - Type '2' is not assignable to type '1'. + Source has 2 element(s) but target allows only 1. ==== tests/cases/conformance/types/tuple/wideningTuples3.ts (2 errors) ==== @@ -12,5 +11,4 @@ tests/cases/conformance/types/tuple/wideningTuples3.ts(3,9): error TS2322: Type !!! error TS7005: Variable 'b' implicitly has an '[any, any]' type. ~ !!! error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '2' is not assignable to type '1'. \ No newline at end of file +!!! error TS2322: Source has 2 element(s) but target allows only 1. \ No newline at end of file diff --git a/tests/baselines/reference/wideningTuples4.errors.txt b/tests/baselines/reference/wideningTuples4.errors.txt index e38035e704183..0f90caa9fa6e2 100644 --- a/tests/baselines/reference/wideningTuples4.errors.txt +++ b/tests/baselines/reference/wideningTuples4.errors.txt @@ -1,6 +1,5 @@ tests/cases/conformance/types/tuple/wideningTuples4.ts(3,9): error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. - Types of property 'length' are incompatible. - Type '2' is not assignable to type '1'. + Source has 2 element(s) but target allows only 1. ==== tests/cases/conformance/types/tuple/wideningTuples4.ts (1 errors) ==== @@ -9,6 +8,5 @@ tests/cases/conformance/types/tuple/wideningTuples4.ts(3,9): error TS2322: Type var b = a = [undefined, null]; ~ !!! error TS2322: Type '[undefined, null]' is not assignable to type '[any]'. -!!! error TS2322: Types of property 'length' are incompatible. -!!! error TS2322: Type '2' is not assignable to type '1'. +!!! error TS2322: Source has 2 element(s) but target allows only 1. b = ["", ""]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/variadicTuples1.ts b/tests/cases/conformance/types/tuple/variadicTuples1.ts new file mode 100644 index 0000000000000..ca9087af294b8 --- /dev/null +++ b/tests/cases/conformance/types/tuple/variadicTuples1.ts @@ -0,0 +1,300 @@ +// @strict: true +// @declaration: true + +// Variadics in tuple types + +type TV0 = [string, ...T]; +type TV1 = [string, ...T, number]; +type TV2 = [string, ...T, number, ...T]; +type TV3 = [string, ...T, ...number[], ...T]; // Error + +// Normalization + +type TN1 = TV1<[boolean, string]>; +type TN2 = TV1<[]>; +type TN3 = TV1<[boolean?]>; +type TN4 = TV1; +type TN5 = TV1<[boolean] | [symbol, symbol]>; +type TN6 = TV1; +type TN7 = TV1; + +// Variadics in array literals + +function tup2(t: [...T], u: [...U]) { + return [1, ...t, 2, ...u, 3] as const; +} + +const t2 = tup2(['hello'], [10, true]); + +function concat(t: [...T], u: [...U]): [...T, ...U] { + return [...t, ...u]; +} + +declare const sa: string[]; + +const tc1 = concat([], []); +const tc2 = concat(['hello'], [42]); +const tc3 = concat([1, 2, 3], sa); +const tc4 = concat(sa, [1, 2, 3]); // Ideally would be [...string[], number, number, number] + +// Spread arguments + +declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; + +function foo2(t1: [number, string], t2: [boolean], a1: number[]) { + foo1(1, 'abc', true, 42, 43, 44); + foo1(...t1, true, 42, 43, 44); + foo1(...t1, ...t2, 42, 43, 44); + foo1(...t1, ...t2, ...a1); + foo1(...t1); // Error + foo1(...t1, 45); // Error +} + +declare function foo3(x: number, ...args: [...T, number]): T; + +function foo4(u: U) { + foo3(1, 2); + foo3(1, 'hello', true, 2); + foo3(1, ...u, 'hi', 2); + foo3(1); +} + +// Contextual typing of array literals + +declare function ft1(t: T): T; +declare function ft2(t: T): readonly [...T]; +declare function ft3(t: [...T]): T; +declare function ft4(t: [...T]): readonly [...T]; + +ft1(['hello', 42]); // (string | number)[] +ft2(['hello', 42]); // readonly (string | number)[] +ft3(['hello', 42]); // [string, number] +ft4(['hello', 42]); // readonly [string, number] + +// Indexing variadic tuple types + +function f0(t: [string, ...T], n: number) { + const a = t[0]; // string + const b = t[1]; // [string, ...T][1] + const c = t[2]; // [string, ...T][2] + const d = t[n]; // [string, ...T][number] +} + +function f1(t: [string, ...T, number], n: number) { + const a = t[0]; // string + const b = t[1]; // [string, ...T, number][1] + const c = t[2]; // [string, ...T, number][2] + const d = t[n]; // [string, ...T, number][number] +} + +// Destructuring variadic tuple types + +function f2(t: [string, ...T]) { + let [...ax] = t; // [string, ...T] + let [b1, ...bx] = t; // string, [...T] + let [c1, c2, ...cx] = t; // string, [string, ...T][1], T[number][] +} + +function f3(t: [string, ...T, number]) { + let [...ax] = t; // [string, ...T, number] + let [b1, ...bx] = t; // string, [...T, number] + let [c1, c2, ...cx] = t; // string, [string, ...T, number][1], (number | T[number])[] +} + +// Mapped types applied to variadic tuple types + +type Arrayify = { [P in keyof T]: T[P][] }; + +type TM1 = Arrayify; // [string[], (number | undefined)[]?, Arrayify, ...boolean[][]] + +type TP1 = Partial<[string, ...T, number]>; // [string?, Partial, number?] +type TP2 = Partial<[string, ...T, ...number[]]>; // [string?, Partial, ...(number | undefined)[]] + +// Reverse mapping through mapped type applied to variadic tuple type + +declare function fm1(t: Arrayify<[string, number, ...T]>): T; + +let tm1 = fm1([['abc'], [42], [true], ['def']]); // [boolean, string] + +// Spread of readonly array-like infers mutable array-like + +declare function fx1(a: string, ...args: T): T; + +function gx1(u: U, v: V) { + fx1('abc'); // [] + fx1('abc', ...u); // U + fx1('abc', ...v); // [...V] + fx1('abc', ...u); // U + fx1('abc', ...v); // Error +} + +declare function fx2(a: string, ...args: T): T; + +function gx2(u: U, v: V) { + fx2('abc'); // [] + fx2('abc', ...u); // U + fx2('abc', ...v); // [...V] + fx2('abc', ...u); // U + fx2('abc', ...v); // V +} + +// Relations involving variadic tuple types + +function f10(x: [string, ...unknown[]], y: [string, ...T], z: [string, ...U]) { + x = y; + x = z; + y = x; // Error + y = z; + z = x; // Error + z = y; // Error +} + +// For a generic type T, [...T] is assignable to T, T is assignable to readonly [...T], and T is assignable +// to [...T] when T is constrained to a mutable array or tuple type. + +function f11(t: T, m: [...T], r: readonly [...T]) { + t = m; + t = r; // Error + m = t; + m = r; // Error + r = t; + r = m; +} + +function f12(t: T, m: [...T], r: readonly [...T]) { + t = m; + t = r; // Error + m = t; // Error + m = r; // Error + r = t; + r = m; +} + +// Inference between variadic tuple types + +type First = T[0]; +type DropFirst = T extends readonly [any, ...infer U] ? U : [...T]; + +type Last = T extends readonly [...infer _, infer U] ? U : undefined; +type DropLast = T extends readonly [...infer U, any] ? U : [...T]; + +type T00 = First<[number, symbol, string]>; +type T01 = First<[symbol, string]>; +type T02 = First<[string]>; +type T03 = First<[number, symbol, ...string[]]>; +type T04 = First<[symbol, ...string[]]>; +type T05 = First; +type T06 = First<[]>; +type T07 = First; +type T08 = First; + +type T10 = DropFirst<[number, symbol, string]>; +type T11 = DropFirst<[symbol, string]>; +type T12 = DropFirst<[string]>; +type T13 = DropFirst<[number, symbol, ...string[]]>; +type T14 = DropFirst<[symbol, ...string[]]>; +type T15 = DropFirst; +type T16 = DropFirst<[]>; +type T17 = DropFirst; +type T18 = DropFirst; + +type T20 = Last<[number, symbol, string]>; +type T21 = Last<[symbol, string]>; +type T22 = Last<[string]>; +type T23 = Last<[number, symbol, ...string[]]>; +type T24 = Last<[symbol, ...string[]]>; +type T25 = Last; +type T26 = Last<[]>; // unknown[], maybe should be [] +type T27 = Last; // unknown, maybe should be any +type T28 = Last; + +type T30 = DropLast<[number, symbol, string]>; +type T31 = DropLast<[symbol, string]>; +type T32 = DropLast<[string]>; +type T33 = DropLast<[number, symbol, ...string[]]>; +type T34 = DropLast<[symbol, ...string[]]>; +type T35 = DropLast; +type T36 = DropLast<[]>; // unknown[], maybe should be [] +type T37 = DropLast; +type T38 = DropLast; + +type R00 = First; +type R01 = First; +type R02 = First; +type R03 = First; +type R04 = First; +type R05 = First; +type R06 = First; + +type R10 = DropFirst; +type R11 = DropFirst; +type R12 = DropFirst; +type R13 = DropFirst; +type R14 = DropFirst; +type R15 = DropFirst; +type R16 = DropFirst; + +type R20 = Last; +type R21 = Last; +type R22 = Last; +type R23 = Last; +type R24 = Last; +type R25 = Last; +type R26 = Last; + +type R30 = DropLast; +type R31 = DropLast; +type R32 = DropLast; +type R33 = DropLast; +type R34 = DropLast; +type R35 = DropLast; +type R36 = DropLast; + +// Inference to [...T, ...U] with implied arity for T + +function curry(f: (...args: [...T, ...U]) => R, ...a: T) { + return (...b: U) => f(...a, ...b); +} + +const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; + +const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number +const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number +const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number +const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number +const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number + +const fn2 = (x: number, b: boolean, ...args: string[]) => 0; + +const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number +const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number +const c12 = curry(fn2, 1, true); // (...args: string[]) => number +const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number + +const fn3 = (...args: string[]) => 0; + +const c20 = curry(fn3); // (...args: string[]) => number +const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number +const c22 = curry(fn3, ...sa); // (...args: string[]) => number + +// No inference to [...T, ...U] when there is no implied arity + +function curry2(f: (...args: [...T, ...U]) => R, t: [...T], u: [...U]) { + return f(...t, ...u); +} + +declare function fn10(a: string, b: number, c: boolean): string[]; + +curry2(fn10, ['hello', 42], [true]); +curry2(fn10, ['hello'], [42, true]); + +// Last argument is contextually typed + +declare function call(...args: [...T, (...args: T) => R]): [T, R]; + +call('hello', 32, (a, b) => 42); + +// Would be nice to infer [...string[], (...args: string[]) => number] here +// Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure + +call(...sa, (...x) => 42);