From 08c0a6c7ffbd17db7754ad2187ebb1d8671ee90f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Nov 2020 14:22:26 -0800 Subject: [PATCH 1/7] Support starting and middle rest elements in tuples --- src/compiler/checker.ts | 242 +++++++++++++++------------ src/compiler/diagnosticMessages.json | 32 +++- src/compiler/types.ts | 19 ++- 3 files changed, 171 insertions(+), 122 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index afb1e6364b5aa..1aef9070af0a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12820,7 +12820,7 @@ namespace ts { // is true for each of the synthesized type parameters. 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; + const minLength = countWhere(elementFlags, f => !!(f & (ElementFlags.Required | ElementFlags.Variadic))); let typeParameters: TypeParameter[] | undefined; const properties: Symbol[] = []; let combinedFlags: ElementFlags = 0; @@ -12877,89 +12877,90 @@ namespace ts { } 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); + return target.objectFlags & ObjectFlags.Tuple ? createNormalizedTupleType(target as TupleType, typeArguments!) : createTypeReference(target, typeArguments); } 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 checkCrossProductUnion(map(elementTypes, (t, i) => target.elementFlags[i] & ElementFlags.Variadic ? t : unknownType)) ? - mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, replaceElement(elementTypes, unionIndex, t))) : - errorType; - } - // 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) { + if (!(target.combinedFlags & ElementFlags.NonRequired)) { + // No need to normalize when we only have regular required elements return createTypeReference(target, elementTypes); } - // We have non-generic variadic elements that need normalization. + if (target.combinedFlags & ElementFlags.Variadic) { + // 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 checkCrossProductUnion(map(elementTypes, (t, i) => target.elementFlags[i] & ElementFlags.Variadic ? t : unknownType)) ? + mapType(elementTypes[unionIndex], t => createNormalizedTupleType(target, replaceElement(elementTypes, unionIndex, t))) : + errorType; + } + } + // We have optional, rest, or variadic elements that may need normalizing. Normalization ensures that all variadic + // elements are generic and that the tuple type has one of the following layouts, disregarding variadic elements: + // (1) Zero or more required elements, followed by zero or more optional elements, followed by zero or one rest element. + // (2) Zero or more required elements, followed by a rest element, followed by zero or more required elements. + // In either layout, zero or more generic variadic elements may be present at any location. const expandedTypes: Type[] = []; const expandedFlags: ElementFlags[] = []; let expandedDeclarations: (NamedTupleMember | ParameterDeclaration)[] | undefined = []; - let optionalIndex = -1; - let restTypes: Type[] | undefined; + let lastRequiredIndex = -1; + let firstRestIndex = -1; + let lastOptionalOrRestIndex = -1; 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]); + // Generic variadic elements stay as they are. + addElement(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])); + forEach(getTypeArguments(type), (t, n) => addElement(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]); + addElement(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]); + addElement(type, flags, target.labeledElementDeclarations?.[i]); } } - if (restTypes) { - // Create a union of the collected rest element types. - expandedTypes[expandedTypes.length - 1] = getUnionType(restTypes); + // Turn optional elements preceding the last required element into required elements + for (let i = 0; i < lastRequiredIndex; i++) { + if (expandedFlags[i] & ElementFlags.Optional) expandedFlags[i] = ElementFlags.Required; + } + if (firstRestIndex >= 0 && firstRestIndex < lastOptionalOrRestIndex) { + // Turn elements between first rest and last optional/rest into a single rest element + expandedTypes[firstRestIndex] = getUnionType(sameMap(expandedTypes.slice(firstRestIndex, lastOptionalOrRestIndex + 1), + (t, i) => expandedFlags[firstRestIndex + i] & ElementFlags.Variadic ? getIndexedAccessType(t, numberType) : t)); + expandedTypes.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); + expandedFlags.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); + expandedDeclarations?.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); } const tupleTarget = getTupleTargetType(expandedFlags, target.readonly, expandedDeclarations); return tupleTarget === emptyGenericType ? emptyObjectType : expandedFlags.length ? createTypeReference(tupleTarget, expandedTypes) : tupleTarget; - 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); + function addElement(type: Type, flags: ElementFlags, declaration: NamedTupleMember | ParameterDeclaration | undefined) { + if (flags & ElementFlags.Required) { + lastRequiredIndex = expandedFlags.length; + } + if (flags & ElementFlags.Rest && firstRestIndex < 0) { + firstRestIndex = expandedFlags.length; + } + if (flags & (ElementFlags.Optional | ElementFlags.Rest)) { + lastOptionalOrRestIndex = expandedFlags.length; + } + expandedTypes.push(type); + expandedFlags.push(flags); + if (expandedDeclarations && declaration) { + expandedDeclarations.push(declaration); } 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; - } + expandedDeclarations = undefined; } } } @@ -12977,6 +12978,17 @@ namespace ts { getIndexType(type.target.readonly ? globalReadonlyArrayType : globalArrayType))); } + // Return count of starting consecutive tuple elements of the given kind(s) + function getStartElementCount(type: TupleType, flags: ElementFlags) { + const index = findIndex(type.elementFlags, f => !(f & flags)); + return index >= 0 ? index : type.elementFlags.length; + } + + // Return count of ending consecutive tuple elements of the given kind(s) + function getEndElementCount(type: TupleType, flags: ElementFlags) { + return type.elementFlags.length - findLastIndex(type.elementFlags, f => !(f & flags)) - 1; + } + function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { const type = getTypeFromTypeNode(node.type); return strictNullChecks ? getOptionalType(type) : type; @@ -18107,48 +18119,61 @@ namespace ts { } 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; - let canExcludeDiscriminants = !!excludedProperties; - 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; + const sourceTypeArguments = getTypeArguments(source); + const targetTypeArguments = getTypeArguments(target); + const startCount = Math.min(isTupleType(source) ? getStartElementCount(source.target, ElementFlags.NonRest) : 0, getStartElementCount(target.target, ElementFlags.NonRest)); + const endCount = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.NonRest) : 0, targetRestFlag ? getEndElementCount(target.target, ElementFlags.NonRest) : 0); + let canExcludeDiscriminants = !!excludedProperties; + for (let i = 0; i < targetArity; i++) { + const sourceIndex = i < targetArity - endCount ? i : i + sourceArity - targetArity; + const sourceFlags = isTupleType(source) && (i < startCount || i >= targetArity - endCount) ? source.target.elementFlags[sourceIndex] : ElementFlags.Rest; + const targetFlags = target.target.elementFlags[i]; + if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic)) { + if (reportErrors) { + reportError(Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, i); } - 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; - } + return Ternary.False; + } + if (sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable)) { + if (reportErrors) { + reportError(Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourceIndex, i); } - // We can only exclude discriminant properties if we have not yet encountered a variable-length element. - if (canExcludeDiscriminants) { - if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) { - canExcludeDiscriminants = false; - } - if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) { - continue; - } + return Ternary.False; + } + if (targetFlags & ElementFlags.Required && !(sourceFlags & ElementFlags.Required)) { + if (reportErrors) { + reportError(Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, i); } - 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; + } + // We can only exclude discriminant properties if we have not yet encountered a variable-length element. + if (canExcludeDiscriminants) { + if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) { + canExcludeDiscriminants = false; + } + if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) { + continue; + } + } + const sourceType = !isTupleType(source) ? sourceTypeArguments[0] : + i < startCount || i >= targetArity - endCount ? sourceTypeArguments[sourceIndex] : + getElementTypeOfSliceOfTupleType(source, startCount, endCount) || neverType; + const targetType = targetTypeArguments[i]; + const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType; + const related = isRelatedTo(sourceType, targetCheckType, reportErrors, /*headMessage*/ undefined, intersectionState); + if (!related) { + if (reportErrors) { + if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) { + reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourceIndex, i); + } + else { + reportIncompatibleError(Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, startCount, sourceArity - endCount - 1, i); } - return Ternary.False; } - result &= related; + return Ternary.False; } + result &= related; + } return result; } @@ -19114,10 +19139,6 @@ namespace ts { return restType && createArrayType(restType); } - function getEndLengthOfType(type: Type) { - return isTupleType(type) ? getTypeReferenceArity(type) - findLastIndex(type.target.elementFlags, f => !(f & (ElementFlags.Required | ElementFlags.Optional))) - 1 : 0; - } - function getElementTypeOfSliceOfTupleType(type: TupleTypeReference, index: number, endSkipCount = 0, writing = false) { const length = getTypeReferenceArity(type) - endSkipCount; if (index < length) { @@ -20440,20 +20461,17 @@ namespace ts { return; } 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; + const endLength = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.Fixed) : 0, + target.target.hasRestElement ? getEndElementCount(target.target, ElementFlags.Fixed) : 0); // Infer between starting fixed elements. for (let i = 0; i < startLength; i++) { inferFromTypes(getTypeArguments(source)[i], elementTypes[i]); } - if (sourceRestType && sourceArity - startLength === 1) { + if (!isTupleType(source) || sourceArity - startLength - endLength === 1 && source.target.elementFlags[startLength] & ElementFlags.Rest) { // Single rest element remains in source, infer from that to every element in target + const restType = getTypeArguments(source)[startLength]; for (let i = startLength; i < targetArity - endLength; i++) { - inferFromTypes(elementFlags[i] & ElementFlags.Variadic ? createArrayType(sourceRestType) : sourceRestType, elementTypes[i]); + inferFromTypes(elementFlags[i] & ElementFlags.Variadic ? createArrayType(restType) : restType, elementTypes[i]); } } else { @@ -20463,20 +20481,20 @@ namespace ts { 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]); + inferFromTypes(sliceTupleType(source, startLength, endLength + sourceArity - targetInfo.impliedArity), elementTypes[startLength]); + inferFromTypes(sliceTupleType(source, startLength + targetInfo.impliedArity, endLength), elementTypes[startLength + 1]); } } 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. // If target ends in optional element(s), make a lower priority a speculative inference. const endsInOptional = target.target.elementFlags[targetArity - 1] & ElementFlags.Optional; - const sourceSlice = isTupleType(source) ? sliceTupleType(source, startLength, sourceEndLength) : createArrayType(sourceRestType!); + const sourceSlice = isTupleType(source) ? sliceTupleType(source, startLength, endLength) : createArrayType(getTypeArguments(source)[0]); inferWithPriority(sourceSlice, elementTypes[startLength], endsInOptional ? InferencePriority.SpeculativeTuple : 0); } 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; + const restType = isTupleType(source) ? getElementTypeOfSliceOfTupleType(source, startLength, endLength) : getTypeArguments(source)[0]; if (restType) { inferFromTypes(restType, elementTypes[startLength]); } @@ -20484,7 +20502,7 @@ namespace ts { } // Infer between ending fixed elements for (let i = 0; i < endLength; i++) { - inferFromTypes(sourceRestType || getTypeArguments(source)[sourceArity - i - 1], elementTypes[targetArity - i - 1]); + inferFromTypes(getTypeArguments(source)[sourceArity - i - 1], elementTypes[targetArity - i - 1]); } return; } @@ -28767,6 +28785,10 @@ namespace ts { return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined); } + // Return the number of parameters in a signature. The rest parameter, if present, counts as one + // parameter. For example, the parameter count of (x: number, y: number, ...z: string[]) is 3 and + // the parameter count of (x: number, ...args: [number, ...string[], boolean])) is also 3. In the + // latter example, the effective rest type is [...string[], boolean]. function getParameterCount(signature: Signature) { const length = signature.parameters.length; if (signatureHasRestParameter(signature)) { @@ -31920,19 +31942,23 @@ namespace ts { } } else if (flags & ElementFlags.Rest) { + if (seenRestElement) { + grammarErrorOnNode(e, Diagnostics.A_rest_element_cannot_follow_another_rest_element); + break; + } seenRestElement = true; } else if (flags & ElementFlags.Optional) { + if (seenRestElement) { + grammarErrorOnNode(e, Diagnostics.An_optional_element_cannot_follow_a_rest_element); + break; + } seenOptionalElement = true; } else if (seenOptionalElement) { grammarErrorOnNode(e, Diagnostics.A_required_element_cannot_follow_an_optional_element); break; } - if (seenRestElement && i !== elementTypes.length - 1) { - grammarErrorOnNode(e, Diagnostics.A_rest_element_must_be_last_in_a_tuple_type); - break; - } } forEach(node.elements, checkSourceElement); getTypeFromTypeNode(node); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 95d40754f37ab..3e52f3a39b983 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -843,10 +843,6 @@ "category": "Error", "code": 1255 }, - "A rest element must be last in a tuple type.": { - "category": "Error", - "code": 1256 - }, "A required element cannot follow an optional element.": { "category": "Error", "code": 1257 @@ -875,6 +871,14 @@ "category": "Error", "code": 1264 }, + "A rest element cannot follow another rest element.": { + "category": "Error", + "code": 1265 + }, + "An optional element cannot follow a rest element.": { + "category": "Error", + "code": 1266 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", @@ -2469,9 +2473,25 @@ "category": "Error", "code": 2621 }, - "Element at index {0} is variadic in one type but not in the other.": { + "Source provides no match for required element at position {0} in target.": { + "category": "Error", + "code": 2623 + }, + "Source provides no match for variadic element at position {0} in target.": { + "category": "Error", + "code": 2624 + }, + "Variadic element at position {0} in source does not match element at position {1} in target.": { + "category": "Error", + "code": 2625 + }, + "Type at position {0} in source is not compatible with type at position {1} in target.": { + "category": "Error", + "code": 2626 + }, + "Type at positions {0} through {1} in source is not compatible with type at position {2} in target.": { "category": "Error", - "code": 2622 + "code": 2627 }, "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 750934077595f..defd9fc67b029 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5166,18 +5166,21 @@ namespace ts { } export const enum ElementFlags { - Required = 1 << 0, // T - Optional = 1 << 1, // T? - Rest = 1 << 2, // ...T[] - Variadic = 1 << 3, // ...T - Variable = Rest | Variadic, + Required = 1 << 0, // T + Optional = 1 << 1, // T? + Rest = 1 << 2, // ...T[] + Variadic = 1 << 3, // ...T + Fixed = Required | Optional, + Variable = Rest | Variadic, + NonRequired = Optional | Rest | Variadic, + NonRest = Required | Optional | Variadic, } export interface TupleType extends GenericType { elementFlags: readonly ElementFlags[]; - minLength: number; - fixedLength: number; - hasRestElement: boolean; + minLength: number; // Number of required or variadic elements + fixedLength: number; // Number of initial required or optional elements + hasRestElement: boolean; // True if tuple has any rest or variadic elements combinedFlags: ElementFlags; readonly: boolean; labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; From c9b8bd1f492c541cdb77d7582a8a770bbd0a12b8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Nov 2020 14:22:48 -0800 Subject: [PATCH 2/7] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 5 ++- tests/baselines/reference/api/typescript.d.ts | 5 ++- tests/baselines/reference/for-of39.errors.txt | 4 +- .../reference/genericRestParameters2.types | 2 +- .../iterableArrayPattern28.errors.txt | 4 +- .../optionalTupleElements1.errors.txt | 24 +++++----- .../reference/restTupleElements1.errors.txt | 29 ++++++------ .../reference/restTupleElements1.types | 2 +- .../restTuplesFromContextualTypes.errors.txt | 4 +- .../reference/spliceTuples.errors.txt | 4 +- .../reference/variadicTuples1.errors.txt | 29 ++++++------ tests/baselines/reference/variadicTuples1.js | 2 +- .../baselines/reference/variadicTuples1.types | 44 +++++++++---------- 13 files changed, 81 insertions(+), 77 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 64b8136ef8e4e..3e52e68a769ba 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2590,7 +2590,10 @@ declare namespace ts { Optional = 2, Rest = 4, Variadic = 8, - Variable = 12 + Fixed = 3, + Variable = 12, + NonRequired = 14, + NonRest = 11 } export interface TupleType extends GenericType { elementFlags: readonly ElementFlags[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2b6547e3c851c..209a58956524b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2590,7 +2590,10 @@ declare namespace ts { Optional = 2, Rest = 4, Variadic = 8, - Variable = 12 + Fixed = 3, + Variable = 12, + NonRequired = 14, + NonRest = 11 } export interface TupleType extends GenericType { elementFlags: readonly ElementFlags[]; diff --git a/tests/baselines/reference/for-of39.errors.txt b/tests/baselines/reference/for-of39.errors.txt index 3ecdc46bcfc49..c887c20ef4b10 100644 --- a/tests/baselines/reference/for-of39.errors.txt +++ b/tests/baselines/reference/for-of39.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,11): error TS2769: No Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorYieldResult'. Type '[string, number] | [string, true]' is not assignable to type 'readonly [string, boolean]'. Type '[string, number]' is not assignable to type 'readonly [string, boolean]'. - Types of property '1' are incompatible. + Type at position 1 in source is not compatible with type at position 1 in target. Type 'number' is not assignable to type 'boolean'. Overload 2 of 3, '(entries?: readonly (readonly [string, boolean])[]): Map', gave the following error. Type 'number' is not assignable to type 'boolean'. @@ -25,7 +25,7 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,11): error TS2769: No !!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorYieldResult'. !!! error TS2769: Type '[string, number] | [string, true]' is not assignable to type 'readonly [string, boolean]'. !!! error TS2769: Type '[string, number]' is not assignable to type 'readonly [string, boolean]'. -!!! error TS2769: Types of property '1' are incompatible. +!!! error TS2769: Type at position 1 in source is not compatible with type at position 1 in target. !!! error TS2769: Type 'number' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 3, '(entries?: readonly (readonly [string, boolean])[]): Map', gave the following error. !!! error TS2769: Type 'number' is not assignable to type 'boolean'. diff --git a/tests/baselines/reference/genericRestParameters2.types b/tests/baselines/reference/genericRestParameters2.types index 9c5bcce5212f4..ed4555c93694f 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[], boolean] >f20 : (...args: T) => T >42 : 42 >"hello" : "hello" diff --git a/tests/baselines/reference/iterableArrayPattern28.errors.txt b/tests/baselines/reference/iterableArrayPattern28.errors.txt index 0778b149183b3..b47f3b2c993b5 100644 --- a/tests/baselines/reference/iterableArrayPattern28.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern28.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,24): error Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorYieldResult'. Type '[string, number] | [string, boolean]' is not assignable to type 'readonly [string, number]'. Type '[string, boolean]' is not assignable to type 'readonly [string, number]'. - Types of property '1' are incompatible. + Type at position 1 in source is not compatible with type at position 1 in target. Type 'boolean' is not assignable to type 'number'. Overload 2 of 3, '(entries?: readonly (readonly [string, number])[]): Map', gave the following error. Type 'boolean' is not assignable to type 'number'. @@ -26,7 +26,7 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,24): error !!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorYieldResult'. !!! error TS2769: Type '[string, number] | [string, boolean]' is not assignable to type 'readonly [string, number]'. !!! error TS2769: Type '[string, boolean]' is not assignable to type 'readonly [string, number]'. -!!! error TS2769: Types of property '1' are incompatible. +!!! error TS2769: Type at position 1 in source is not compatible with type at position 1 in target. !!! error TS2769: Type 'boolean' is not assignable to type 'number'. !!! error TS2769: Overload 2 of 3, '(entries?: readonly (readonly [string, number])[]): Map', gave the following error. !!! error TS2769: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/optionalTupleElements1.errors.txt b/tests/baselines/reference/optionalTupleElements1.errors.txt index 148c66977429e..1ea923111f82a 100644 --- a/tests/baselines/reference/optionalTupleElements1.errors.txt +++ b/tests/baselines/reference/optionalTupleElements1.errors.txt @@ -1,16 +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'. - Property '2' is optional in type '[number, string, (boolean | undefined)?]' but required in type '[number, string, boolean]'. + Source provides no match for required element at position 2 in target. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(16,5): error TS2322: Type 'T3' is not assignable to type 'T1'. - Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. + Source provides no match for required element at position 1 in target. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(17,5): error TS2322: Type 'T4' is not assignable to type 'T1'. - Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. + Source provides no match for required element at position 0 in target. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(20,5): error TS2322: Type 'T3' is not assignable to type 'T2'. - Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. + Source provides no match for required element at position 1 in target. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(21,5): error TS2322: Type 'T4' is not assignable to type 'T2'. - Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. + Source provides no match for required element at position 0 in target. tests/cases/conformance/types/tuple/optionalTupleElements1.ts(25,5): error TS2322: Type 'T4' is not assignable to type 'T3'. - Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, (string | undefined)?, (boolean | undefined)?]'. + Source provides no match for required element at position 0 in target. ==== tests/cases/conformance/types/tuple/optionalTupleElements1.ts (7 errors) ==== @@ -33,32 +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: Property '2' is optional in type '[number, string, (boolean | undefined)?]' but required in type '[number, string, boolean]'. +!!! error TS2322: Source provides no match for required element at position 2 in target. t1 = t3; // Error ~~ !!! error TS2322: Type 'T3' is not assignable to type 'T1'. -!!! error TS2322: Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. +!!! error TS2322: Source provides no match for required element at position 1 in target. t1 = t4; // Error ~~ !!! error TS2322: Type 'T4' is not assignable to type 'T1'. -!!! error TS2322: Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, boolean]'. +!!! error TS2322: Source provides no match for required element at position 0 in target. t2 = t1; t2 = t2; t2 = t3; // Error ~~ !!! error TS2322: Type 'T3' is not assignable to type 'T2'. -!!! error TS2322: Property '1' is optional in type '[number, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. +!!! error TS2322: Source provides no match for required element at position 1 in target. t2 = t4; // Error ~~ !!! error TS2322: Type 'T4' is not assignable to type 'T2'. -!!! error TS2322: Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, string, (boolean | undefined)?]'. +!!! error TS2322: Source provides no match for required element at position 0 in target. t3 = t1; t3 = t2; t3 = t3; t3 = t4; // Error ~~ !!! error TS2322: Type 'T4' is not assignable to type 'T3'. -!!! error TS2322: Property '0' is optional in type '[(number | undefined)?, (string | undefined)?, (boolean | undefined)?]' but required in type '[number, (string | undefined)?, (boolean | undefined)?]'. +!!! error TS2322: Source provides no match for required element at position 0 in target. t4 = t1; t4 = t2; t4 = t3; diff --git a/tests/baselines/reference/restTupleElements1.errors.txt b/tests/baselines/reference/restTupleElements1.errors.txt index 304046672a189..a09d7bebe7257 100644 --- a/tests/baselines/reference/restTupleElements1.errors.txt +++ b/tests/baselines/reference/restTupleElements1.errors.txt @@ -1,10 +1,9 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(3,22): error TS1257: A required element cannot follow an optional element. -tests/cases/conformance/types/tuple/restTupleElements1.ts(8,13): error TS1256: A rest element must be last in a tuple type. tests/cases/conformance/types/tuple/restTupleElements1.ts(9,13): error TS2574: A rest element type must be an array type. 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 optional in type 'number[]' but required in type '[number, ...number[]]'. + Source provides no match for required element at position 0 in target. tests/cases/conformance/types/tuple/restTupleElements1.ts(24,31): error TS2344: Type '[]' does not satisfy the constraint '[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]'. @@ -16,16 +15,18 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(32,31): error TS2344: 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[]]'. - Types of property '2' are incompatible. - Type 'string' is not assignable to type 'number'. + Type at positions 1 through 2 in source is not compatible with type at position 1 in target. + Type 'string | number' is not assignable to type 'number'. + 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[]]'. - Types of property '3' are incompatible. - Type 'string' is not assignable to type 'number'. + Type at positions 1 through 3 in source is not compatible with type at position 1 in target. + Type 'string | number' is not assignable to type 'number'. + 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[]]'. Source has 0 element(s) but target requires 1. -==== tests/cases/conformance/types/tuple/restTupleElements1.ts (14 errors) ==== +==== tests/cases/conformance/types/tuple/restTupleElements1.ts (13 errors) ==== type T00 = [string?]; type T01 = [string, string?]; type T02 = [string?, string]; // Error @@ -36,8 +37,6 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A type T05 = [...[...[...string[]]]]; type T06 = [string, ...string[]]; type T07 = [...string[], string]; // Error - ~~~~~~~~~~~ -!!! error TS1256: A rest element must be last in a tuple type. type T08 = [...string]; // Error ~~~~~~~~~ !!! error TS2574: A rest element type must be an array type. @@ -61,7 +60,7 @@ 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 optional in type 'number[]' but required in type '[number, ...number[]]'. +!!! error TS2344: Source provides no match for required element at position 0 in target. assign<[number, ...number[]], []>(); // Error ~~ !!! error TS2344: Type '[]' does not satisfy the constraint '[number, ...number[]]'. @@ -90,13 +89,15 @@ 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: Types of property '2' are incompatible. -!!! error TS2344: Type 'string' is not assignable to type 'number'. +!!! error TS2344: Type at positions 1 through 2 in source is not compatible with type at position 1 in target. +!!! error TS2344: Type 'string | number' is not assignable to type 'number'. +!!! 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: Types of property '3' are incompatible. -!!! error TS2344: Type 'string' is not assignable to type 'number'. +!!! error TS2344: Type at positions 1 through 3 in source is not compatible with type at position 1 in target. +!!! error TS2344: Type 'string | number' is not assignable to type 'number'. +!!! error TS2344: Type 'string' is not assignable to type 'number'. type T20 = [number, string, ...boolean[]]; diff --git a/tests/baselines/reference/restTupleElements1.types b/tests/baselines/reference/restTupleElements1.types index a910315c51d82..c283de08148d9 100644 --- a/tests/baselines/reference/restTupleElements1.types +++ b/tests/baselines/reference/restTupleElements1.types @@ -107,7 +107,7 @@ type T21 = T20[0]; >T21 : number type T22 = T20[0 | 1]; ->T22 : T22 +>T22 : string | number 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 31b1845e2f458..e182b72f57cdd 100644 --- a/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt +++ b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error Types of parameters 'b' and 'args' are incompatible. Type 'T' is not assignable to 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][]]'. + Source provides no match for required element at position 0 in target. ==== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts (1 errors) ==== @@ -67,7 +67,7 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error !!! 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: 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][]]'. +!!! error TS2345: Source provides no match for required element at position 0 in target. } declare function f5(f: (...args: T) => U): (...args: T) => U; diff --git a/tests/baselines/reference/spliceTuples.errors.txt b/tests/baselines/reference/spliceTuples.errors.txt index 7346c7b1f820e..f406a1bce0ae2 100644 --- a/tests/baselines/reference/spliceTuples.errors.txt +++ b/tests/baselines/reference/spliceTuples.errors.txt @@ -1,5 +1,5 @@ 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[]]'. + Source provides no match for required element at position 3 in target. ==== tests/cases/compiler/spliceTuples.ts (1 errors) ==== @@ -28,5 +28,5 @@ tests/cases/compiler/spliceTuples.ts(23,1): error TS2322: Type '[number, string, k6 = [1, ...sbb_]; ~~ !!! 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[]]'. +!!! error TS2322: Source provides no match for required element at position 3 in target. \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 416565221bbff..9da33aed396fc 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -1,6 +1,7 @@ -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(52,5): error TS2555: Expected at least 3 arguments, but got 2. tests/cases/conformance/types/tuple/variadicTuples1.ts(53,17): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(62,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[...unknown[], number]'. + Source has 0 element(s) but target requires 1. tests/cases/conformance/types/tuple/variadicTuples1.ts(131,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(149,5): error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...T]'. @@ -39,22 +40,19 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ 'U' could be instantiated with an arbitrary type which could be unrelated to 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. Type '"2"' is not assignable to type 'number | "0" | "length" | "toString" | "toLocaleString" | "pop" | "push" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" | "1"'. -tests/cases/conformance/types/tuple/variadicTuples1.ts(346,14): error TS7019: Rest parameter 'x' implicitly has an 'any[]' type. tests/cases/conformance/types/tuple/variadicTuples1.ts(354,26): error TS2322: Type 'string' is not assignable to type 'number | undefined'. -tests/cases/conformance/types/tuple/variadicTuples1.ts(393,19): error TS1256: A rest element must be last in a tuple type. -tests/cases/conformance/types/tuple/variadicTuples1.ts(396,20): error TS1256: A rest element must be last in a tuple type. -tests/cases/conformance/types/tuple/variadicTuples1.ts(397,12): error TS1256: A rest element must be last in a tuple type. +tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. + Type at position 0 in source is not compatible with type at position 0 in target. + Type 'boolean' is not assignable to type 'number'. -==== tests/cases/conformance/types/tuple/variadicTuples1.ts (23 errors) ==== +==== tests/cases/conformance/types/tuple/variadicTuples1.ts (20 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 @@ -116,6 +114,9 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,12): error TS1256: A foo3(1, 'hello', true, 2); foo3(1, ...u, 'hi', 2); foo3(1); + ~~~~~~~ +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[...unknown[], number]'. +!!! error TS2345: Source has 0 element(s) but target requires 1. } // Contextual typing of array literals @@ -453,8 +454,6 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,12): error TS1256: A // 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 inference to ending optional elements (except with identical structure) @@ -504,15 +503,13 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,12): error TS1256: A type Numbers = number[]; type Unbounded = [...Numbers, boolean]; - ~~~~~~~~~~ -!!! error TS1256: A rest element must be last in a tuple type. const data: Unbounded = [false, false]; + ~~~~ +!!! error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. +!!! error TS2322: Type at position 0 in source is not compatible with type at position 0 in target. +!!! error TS2322: Type 'boolean' is not assignable to type 'number'. type U1 = [string, ...Numbers, boolean]; - ~~~~~~~~~~ -!!! error TS1256: A rest element must be last in a tuple type. type U2 = [...[string, ...Numbers], boolean]; - ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1256: A rest element must be last in a tuple type. type U3 = [...[string, number], boolean]; \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples1.js b/tests/baselines/reference/variadicTuples1.js index ee7ebc5c6a769..cfc520aa14d40 100644 --- a/tests/baselines/reference/variadicTuples1.js +++ b/tests/baselines/reference/variadicTuples1.js @@ -641,7 +641,7 @@ 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 const tc4: [...string[], number, number, number]; declare function concat2(t: T, u: U): (T[number] | U[number])[]; declare const tc5: (2 | 4 | 1 | 3 | 6 | 5)[]; declare function foo1(a: number, b: string, c: boolean, ...d: number[]): void; diff --git a/tests/baselines/reference/variadicTuples1.types b/tests/baselines/reference/variadicTuples1.types index ccc9ce8c4edb4..255eefabc34df 100644 --- a/tests/baselines/reference/variadicTuples1.types +++ b/tests/baselines/reference/variadicTuples1.types @@ -25,13 +25,13 @@ type TN3 = TV1<[boolean?]>; >TN3 : [string, boolean | undefined, number] type TN4 = TV1; ->TN4 : [string, ...(string | number)[]] +>TN4 : [string, ...string[], number] type TN5 = TV1<[boolean] | [symbol, symbol]>; >TN5 : [string, boolean, number] | [string, symbol, symbol, number] type TN6 = TV1; ->TN6 : [string, ...any[]] +>TN6 : [string, ...any[], number] type TN7 = TV1; >TN7 : never @@ -108,8 +108,8 @@ const tc3 = concat([1, 2, 3], sa); >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)[] +>tc4 : [...string[], number, number, number] +>concat(sa, [1, 2, 3]) : [...string[], number, number, number] >concat : (t: [...T], u: [...U]) => [...T, ...U] >sa : string[] >[1, 2, 3] : [number, number, number] @@ -854,16 +854,16 @@ type T22 = Last<[string]>; >T22 : string type T23 = Last<[number, symbol, ...string[]]>; ->T23 : string +>T23 : unknown type T24 = Last<[symbol, ...string[]]>; ->T24 : string +>T24 : unknown type T25 = Last<[string?]>; >T25 : string | undefined type T26 = Last; ->T26 : string +>T26 : string | undefined type T27 = Last<[]>; // unknown, maybe should undefined >T27 : unknown @@ -884,10 +884,10 @@ type T32 = DropLast<[string]>; >T32 : [] type T33 = DropLast<[number, symbol, ...string[]]>; ->T33 : [number, symbol, ...string[]] +>T33 : unknown[] type T34 = DropLast<[symbol, ...string[]]>; ->T34 : [symbol, ...string[]] +>T34 : unknown[] type T35 = DropLast<[string?]>; >T35 : [] @@ -956,13 +956,13 @@ type R22 = Last; >R22 : string type R23 = Last; ->R23 : string +>R23 : unknown type R24 = Last; ->R24 : string +>R24 : unknown type R25 = Last; ->R25 : string +>R25 : string | undefined type R26 = Last; >R26 : unknown @@ -977,10 +977,10 @@ type R32 = DropLast; >R32 : [] type R33 = DropLast; ->R33 : [number, symbol, ...string[]] +>R33 : unknown[] type R34 = DropLast; ->R34 : [symbol, ...string[]] +>R34 : unknown[] type R35 = DropLast; >R35 : string[] @@ -1241,12 +1241,12 @@ call('hello', 32, (a, b) => 42); // 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(...sa, (...x) => 42) : [string[], number] >call : (...args: [...T, (...args: T) => R]) => [T, R] >...sa : string >sa : string[] ->(...x) => 42 : (...x: any[]) => number ->x : any[] +>(...x) => 42 : (...x: string[]) => number +>x : string[] >42 : 42 // No inference to ending optional elements (except with identical structure) @@ -1389,19 +1389,19 @@ type Numbers = number[]; >Numbers : Numbers type Unbounded = [...Numbers, boolean]; ->Unbounded : (number | boolean)[] +>Unbounded : [...number[], boolean] const data: Unbounded = [false, false]; ->data : (number | boolean)[] ->[false, false] : false[] +>data : [...number[], boolean] +>[false, false] : [false, false] >false : false >false : false type U1 = [string, ...Numbers, boolean]; ->U1 : [string, ...(number | boolean)[]] +>U1 : [string, ...number[], boolean] type U2 = [...[string, ...Numbers], boolean]; ->U2 : [string, ...(number | boolean)[]] +>U2 : [string, ...number[], boolean] type U3 = [...[string, number], boolean]; >U3 : [string, number, boolean] From 9c277396915b09ede48b49466998e47e9db85cc3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Nov 2020 07:34:25 -0800 Subject: [PATCH 3/7] Include all rest arguments in error span --- src/compiler/checker.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1aef9070af0a6..9e91a31b57c5c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26926,7 +26926,11 @@ namespace ts { } if (restType) { const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined, checkMode); - const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined; + const restArgCount = args.length - argCount; + const errorNode = !reportErrors ? undefined : + restArgCount === 0 ? node : + restArgCount === 1 ? args[argCount] : + setTextRangePosEnd(createSyntheticExpression(node, spreadType), args[argCount].pos, args[args.length - 1].end); if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) { Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors"); maybeAddMissingAwaitInfo(errorNode, spreadType, restType); From af4d6f59a4c9fa594f40c97fa2b09af46d9eb308 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Nov 2020 07:35:05 -0800 Subject: [PATCH 4/7] Accept new baselines --- tests/baselines/reference/genericRestParameters3.errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/genericRestParameters3.errors.txt b/tests/baselines/reference/genericRestParameters3.errors.txt index 72620c41027dc..3b002686faa2e 100644 --- a/tests/baselines/reference/genericRestParameters3.errors.txt +++ b/tests/baselines/reference/genericRestParameters3.errors.txt @@ -114,7 +114,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 let a = bar(10, 20); let b = bar>(10, 20); // Error - ~~ + ~~~~~~ !!! error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray'. !!! error TS2345: Property 'hello' is missing in type '[10, 20]' but required in type 'CoolArray'. !!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here. @@ -133,7 +133,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 !!! error TS2345: Property 'hello' is missing in type '[number]' but required in type 'CoolArray'. !!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here. baz(1, 2); // Error - ~ + ~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray'. !!! error TS2345: Property 'hello' is missing in type '[number, number]' but required in type 'CoolArray'. !!! related TS2728 tests/cases/conformance/types/rest/genericRestParameters3.ts:30:5: 'hello' is declared here. From 23de9f25ca5fe5e977f42097893befc50d33904a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Nov 2020 14:22:09 -0800 Subject: [PATCH 5/7] Fix tests --- .../reference/variadicTuples1.errors.txt | 31 +- tests/baselines/reference/variadicTuples1.js | 39 +- .../reference/variadicTuples1.symbols | 739 +++++++++--------- .../baselines/reference/variadicTuples1.types | 58 +- .../types/tuple/variadicTuples1.ts | 27 +- 5 files changed, 456 insertions(+), 438 deletions(-) diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 9da33aed396fc..4b457d2eed6f6 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -40,8 +40,8 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ 'U' could be instantiated with an arbitrary type which could be unrelated to 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. Type '"2"' is not assignable to type 'number | "0" | "length" | "toString" | "toLocaleString" | "pop" | "push" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" | "1"'. -tests/cases/conformance/types/tuple/variadicTuples1.ts(354,26): error TS2322: Type 'string' is not assignable to type 'number | undefined'. -tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. Type at position 0 in source is not compatible with type at position 0 in target. Type 'boolean' is not assignable to type 'number'. @@ -52,7 +52,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Typ type TV0 = [string, ...T]; type TV1 = [string, ...T, number]; type TV2 = [string, ...T, number, ...T]; - type TV3 = [string, ...T, ...number[], ...T]; // Error + type TV3 = [string, ...T, ...number[], ...T]; // Normalization @@ -315,11 +315,18 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Typ // Inference between variadic tuple types - type First = T[0]; - type DropFirst = T extends readonly [any?, ...infer U] ? U : [...T]; + type First = + T extends readonly [unknown, ...unknown[]] ? T[0] : + T[0] | undefined; - type Last = T extends readonly [...infer _, infer U] ? U : T extends readonly [...infer _, (infer U)?] ? U | undefined : undefined; - type DropLast = T extends readonly [...infer U, any?] ? U : [...T]; + type DropFirst = T extends readonly [unknown?, ...infer U] ? U : [...T]; + + type Last = + T extends readonly [...unknown[], infer U] ? U : + T extends readonly [unknown, ...unknown[]] ? T[number] : + T[number] | undefined; + + type DropLast = T extends readonly [...infer U, unknown] ? U : [...T]; type T00 = First<[number, symbol, string]>; type T01 = First<[symbol, string]>; @@ -350,8 +357,8 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Typ type T24 = Last<[symbol, ...string[]]>; type T25 = Last<[string?]>; type T26 = Last; - type T27 = Last<[]>; // unknown, maybe should undefined - type T28 = Last; // unknown, maybe should be any + type T27 = Last<[]>; + type T28 = Last; type T29 = Last; type T30 = DropLast<[number, symbol, string]>; @@ -449,10 +456,6 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Typ 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); // No inference to ending optional elements (except with identical structure) @@ -503,7 +506,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(394,7): error TS2322: Typ type Numbers = number[]; type Unbounded = [...Numbers, boolean]; - const data: Unbounded = [false, false]; + const data: Unbounded = [false, false]; // Error ~~~~ !!! error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. !!! error TS2322: Type at position 0 in source is not compatible with type at position 0 in target. diff --git a/tests/baselines/reference/variadicTuples1.js b/tests/baselines/reference/variadicTuples1.js index cfc520aa14d40..03e0167d8dc28 100644 --- a/tests/baselines/reference/variadicTuples1.js +++ b/tests/baselines/reference/variadicTuples1.js @@ -4,7 +4,7 @@ type TV0 = [string, ...T]; type TV1 = [string, ...T, number]; type TV2 = [string, ...T, number, ...T]; -type TV3 = [string, ...T, ...number[], ...T]; // Error +type TV3 = [string, ...T, ...number[], ...T]; // Normalization @@ -206,11 +206,18 @@ function f15(k0: keyof T, k1: keyof [...T], k2: // Inference between variadic tuple types -type First = T[0]; -type DropFirst = T extends readonly [any?, ...infer U] ? U : [...T]; +type First = + T extends readonly [unknown, ...unknown[]] ? T[0] : + T[0] | undefined; -type Last = T extends readonly [...infer _, infer U] ? U : T extends readonly [...infer _, (infer U)?] ? U | undefined : undefined; -type DropLast = T extends readonly [...infer U, any?] ? U : [...T]; +type DropFirst = T extends readonly [unknown?, ...infer U] ? U : [...T]; + +type Last = + T extends readonly [...unknown[], infer U] ? U : + T extends readonly [unknown, ...unknown[]] ? T[number] : + T[number] | undefined; + +type DropLast = T extends readonly [...infer U, unknown] ? U : [...T]; type T00 = First<[number, symbol, string]>; type T01 = First<[symbol, string]>; @@ -241,8 +248,8 @@ type T23 = Last<[number, symbol, ...string[]]>; type T24 = Last<[symbol, ...string[]]>; type T25 = Last<[string?]>; type T26 = Last; -type T27 = Last<[]>; // unknown, maybe should undefined -type T28 = Last; // unknown, maybe should be any +type T27 = Last<[]>; +type T28 = Last; type T29 = Last; type T30 = DropLast<[number, symbol, string]>; @@ -340,10 +347,6 @@ ft(['a', 'b'], ['c', 'd', 42]) 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); // No inference to ending optional elements (except with identical structure) @@ -392,7 +395,7 @@ callApi(getOrgUser); type Numbers = number[]; type Unbounded = [...Numbers, boolean]; -const data: Unbounded = [false, false]; +const data: Unbounded = [false, false]; // Error type U1 = [string, ...Numbers, boolean]; type U2 = [...[string, ...Numbers], boolean]; @@ -588,8 +591,6 @@ ft([1, 2], [1, 2, 3]); ft(['a', 'b'], ['c', 'd']); ft(['a', 'b'], ['c', 'd', 42]); 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++) { @@ -619,7 +620,7 @@ function callApi(method) { } callApi(getUser); callApi(getOrgUser); -var data = [false, false]; +var data = [false, false]; // Error //// [variadicTuples1.d.ts] @@ -674,10 +675,10 @@ declare function f12(t: T, m: [...T], r: readonly declare function f13(t0: T, t1: [...T], t2: [...U]): void; declare function f14(t0: T, t1: [...T], t2: [...U]): void; declare function f15(k0: keyof T, k1: keyof [...T], k2: keyof [...U], k3: keyof [1, 2, ...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 : T extends readonly [...infer _, (infer U)?] ? U | undefined : undefined; -declare type DropLast = T extends readonly [...infer U, any?] ? U : [...T]; +declare type First = T extends readonly [unknown, ...unknown[]] ? T[0] : T[0] | undefined; +declare type DropFirst = T extends readonly [unknown?, ...infer U] ? U : [...T]; +declare type Last = T extends readonly [...unknown[], infer U] ? U : T extends readonly [unknown, ...unknown[]] ? T[number] : T[number] | undefined; +declare type DropLast = T extends readonly [...infer U, unknown] ? U : [...T]; declare type T00 = First<[number, symbol, string]>; declare type T01 = First<[symbol, string]>; declare type T02 = First<[string]>; diff --git a/tests/baselines/reference/variadicTuples1.symbols b/tests/baselines/reference/variadicTuples1.symbols index b8029f3fbc0dc..f6324893994f1 100644 --- a/tests/baselines/reference/variadicTuples1.symbols +++ b/tests/baselines/reference/variadicTuples1.symbols @@ -17,7 +17,7 @@ type TV2 = [string, ...T, number, ...T]; >T : Symbol(T, Decl(variadicTuples1.ts, 4, 9)) >T : Symbol(T, Decl(variadicTuples1.ts, 4, 9)) -type TV3 = [string, ...T, ...number[], ...T]; // Error +type TV3 = [string, ...T, ...number[], ...T]; >TV3 : Symbol(TV3, Decl(variadicTuples1.ts, 4, 61)) >T : Symbol(T, Decl(variadicTuples1.ts, 5, 9)) >T : Symbol(T, Decl(variadicTuples1.ts, 5, 9)) @@ -691,663 +691,670 @@ function f15(k0: keyof T, k1: keyof [...T], k2: // Inference between variadic tuple types -type First = T[0]; +type First = >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 207, 11)) + + T extends readonly [unknown, ...unknown[]] ? T[0] : >T : Symbol(T, Decl(variadicTuples1.ts, 207, 11)) >T : Symbol(T, Decl(variadicTuples1.ts, 207, 11)) -type DropFirst = T extends readonly [any?, ...infer U] ? U : [...T]; ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) ->T : Symbol(T, Decl(variadicTuples1.ts, 208, 15)) ->T : Symbol(T, Decl(variadicTuples1.ts, 208, 15)) ->U : Symbol(U, Decl(variadicTuples1.ts, 208, 81)) ->U : Symbol(U, Decl(variadicTuples1.ts, 208, 81)) ->T : Symbol(T, Decl(variadicTuples1.ts, 208, 15)) - -type Last = T extends readonly [...infer _, infer U] ? U : T extends readonly [...infer _, (infer U)?] ? U | undefined : undefined; ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) ->T : Symbol(T, Decl(variadicTuples1.ts, 210, 10)) ->T : Symbol(T, Decl(variadicTuples1.ts, 210, 10)) ->_ : Symbol(_, Decl(variadicTuples1.ts, 210, 70)) ->U : Symbol(U, Decl(variadicTuples1.ts, 210, 79)) ->U : Symbol(U, Decl(variadicTuples1.ts, 210, 79)) ->T : Symbol(T, Decl(variadicTuples1.ts, 210, 10)) ->_ : Symbol(_, Decl(variadicTuples1.ts, 210, 117)) ->U : Symbol(U, Decl(variadicTuples1.ts, 210, 127)) ->U : Symbol(U, Decl(variadicTuples1.ts, 210, 127)) - -type DropLast = T extends readonly [...infer U, any?] ? U : [...T]; ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) ->T : Symbol(T, Decl(variadicTuples1.ts, 211, 14)) ->T : Symbol(T, Decl(variadicTuples1.ts, 211, 14)) ->U : Symbol(U, Decl(variadicTuples1.ts, 211, 74)) ->U : Symbol(U, Decl(variadicTuples1.ts, 211, 74)) ->T : Symbol(T, Decl(variadicTuples1.ts, 211, 14)) + T[0] | undefined; +>T : Symbol(T, Decl(variadicTuples1.ts, 207, 11)) + +type DropFirst = T extends readonly [unknown?, ...infer U] ? U : [...T]; +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 211, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 211, 15)) +>U : Symbol(U, Decl(variadicTuples1.ts, 211, 85)) +>U : Symbol(U, Decl(variadicTuples1.ts, 211, 85)) +>T : Symbol(T, Decl(variadicTuples1.ts, 211, 15)) + +type Last = +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) +>T : Symbol(T, Decl(variadicTuples1.ts, 213, 10)) + + T extends readonly [...unknown[], infer U] ? U : +>T : Symbol(T, Decl(variadicTuples1.ts, 213, 10)) +>U : Symbol(U, Decl(variadicTuples1.ts, 214, 43)) +>U : Symbol(U, Decl(variadicTuples1.ts, 214, 43)) + + T extends readonly [unknown, ...unknown[]] ? T[number] : +>T : Symbol(T, Decl(variadicTuples1.ts, 213, 10)) +>T : Symbol(T, Decl(variadicTuples1.ts, 213, 10)) + + T[number] | undefined; +>T : Symbol(T, Decl(variadicTuples1.ts, 213, 10)) + +type DropLast = T extends readonly [...infer U, unknown] ? U : [...T]; +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) +>T : Symbol(T, Decl(variadicTuples1.ts, 218, 14)) +>T : Symbol(T, Decl(variadicTuples1.ts, 218, 14)) +>U : Symbol(U, Decl(variadicTuples1.ts, 218, 74)) +>U : Symbol(U, Decl(variadicTuples1.ts, 218, 74)) +>T : Symbol(T, Decl(variadicTuples1.ts, 218, 14)) type T00 = First<[number, symbol, string]>; ->T00 : Symbol(T00, Decl(variadicTuples1.ts, 211, 97)) +>T00 : Symbol(T00, Decl(variadicTuples1.ts, 218, 100)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T01 = First<[symbol, string]>; ->T01 : Symbol(T01, Decl(variadicTuples1.ts, 213, 43)) +>T01 : Symbol(T01, Decl(variadicTuples1.ts, 220, 43)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T02 = First<[string]>; ->T02 : Symbol(T02, Decl(variadicTuples1.ts, 214, 35)) +>T02 : Symbol(T02, Decl(variadicTuples1.ts, 221, 35)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T03 = First<[number, symbol, ...string[]]>; ->T03 : Symbol(T03, Decl(variadicTuples1.ts, 215, 27)) +>T03 : Symbol(T03, Decl(variadicTuples1.ts, 222, 27)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T04 = First<[symbol, ...string[]]>; ->T04 : Symbol(T04, Decl(variadicTuples1.ts, 216, 48)) +>T04 : Symbol(T04, Decl(variadicTuples1.ts, 223, 48)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T05 = First<[string?]>; ->T05 : Symbol(T05, Decl(variadicTuples1.ts, 217, 40)) +>T05 : Symbol(T05, Decl(variadicTuples1.ts, 224, 40)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T06 = First; ->T06 : Symbol(T06, Decl(variadicTuples1.ts, 218, 28)) +>T06 : Symbol(T06, Decl(variadicTuples1.ts, 225, 28)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T07 = First<[]>; ->T07 : Symbol(T07, Decl(variadicTuples1.ts, 219, 27)) +>T07 : Symbol(T07, Decl(variadicTuples1.ts, 226, 27)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T08 = First; ->T08 : Symbol(T08, Decl(variadicTuples1.ts, 220, 21)) +>T08 : Symbol(T08, Decl(variadicTuples1.ts, 227, 21)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T09 = First; ->T09 : Symbol(T09, Decl(variadicTuples1.ts, 221, 22)) +>T09 : Symbol(T09, Decl(variadicTuples1.ts, 228, 22)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type T10 = DropFirst<[number, symbol, string]>; ->T10 : Symbol(T10, Decl(variadicTuples1.ts, 222, 24)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T10 : Symbol(T10, Decl(variadicTuples1.ts, 229, 24)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T11 = DropFirst<[symbol, string]>; ->T11 : Symbol(T11, Decl(variadicTuples1.ts, 224, 47)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T11 : Symbol(T11, Decl(variadicTuples1.ts, 231, 47)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T12 = DropFirst<[string]>; ->T12 : Symbol(T12, Decl(variadicTuples1.ts, 225, 39)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T12 : Symbol(T12, Decl(variadicTuples1.ts, 232, 39)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T13 = DropFirst<[number, symbol, ...string[]]>; ->T13 : Symbol(T13, Decl(variadicTuples1.ts, 226, 31)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T13 : Symbol(T13, Decl(variadicTuples1.ts, 233, 31)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T14 = DropFirst<[symbol, ...string[]]>; ->T14 : Symbol(T14, Decl(variadicTuples1.ts, 227, 52)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T14 : Symbol(T14, Decl(variadicTuples1.ts, 234, 52)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T15 = DropFirst<[string?]>; ->T15 : Symbol(T15, Decl(variadicTuples1.ts, 228, 44)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T15 : Symbol(T15, Decl(variadicTuples1.ts, 235, 44)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T16 = DropFirst; ->T16 : Symbol(T16, Decl(variadicTuples1.ts, 229, 32)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T16 : Symbol(T16, Decl(variadicTuples1.ts, 236, 32)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T17 = DropFirst<[]>; ->T17 : Symbol(T17, Decl(variadicTuples1.ts, 230, 31)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T17 : Symbol(T17, Decl(variadicTuples1.ts, 237, 31)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T18 = DropFirst; ->T18 : Symbol(T18, Decl(variadicTuples1.ts, 231, 25)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T18 : Symbol(T18, Decl(variadicTuples1.ts, 238, 25)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T19 = DropFirst; ->T19 : Symbol(T19, Decl(variadicTuples1.ts, 232, 26)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>T19 : Symbol(T19, Decl(variadicTuples1.ts, 239, 26)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type T20 = Last<[number, symbol, string]>; ->T20 : Symbol(T20, Decl(variadicTuples1.ts, 233, 28)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T20 : Symbol(T20, Decl(variadicTuples1.ts, 240, 28)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T21 = Last<[symbol, string]>; ->T21 : Symbol(T21, Decl(variadicTuples1.ts, 235, 42)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T21 : Symbol(T21, Decl(variadicTuples1.ts, 242, 42)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T22 = Last<[string]>; ->T22 : Symbol(T22, Decl(variadicTuples1.ts, 236, 34)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T22 : Symbol(T22, Decl(variadicTuples1.ts, 243, 34)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T23 = Last<[number, symbol, ...string[]]>; ->T23 : Symbol(T23, Decl(variadicTuples1.ts, 237, 26)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T23 : Symbol(T23, Decl(variadicTuples1.ts, 244, 26)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T24 = Last<[symbol, ...string[]]>; ->T24 : Symbol(T24, Decl(variadicTuples1.ts, 238, 47)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T24 : Symbol(T24, Decl(variadicTuples1.ts, 245, 47)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T25 = Last<[string?]>; ->T25 : Symbol(T25, Decl(variadicTuples1.ts, 239, 39)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T25 : Symbol(T25, Decl(variadicTuples1.ts, 246, 39)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T26 = Last; ->T26 : Symbol(T26, Decl(variadicTuples1.ts, 240, 27)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T26 : Symbol(T26, Decl(variadicTuples1.ts, 247, 27)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) -type T27 = Last<[]>; // unknown, maybe should undefined ->T27 : Symbol(T27, Decl(variadicTuples1.ts, 241, 26)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +type T27 = Last<[]>; +>T27 : Symbol(T27, Decl(variadicTuples1.ts, 248, 26)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) -type T28 = Last; // unknown, maybe should be any ->T28 : Symbol(T28, Decl(variadicTuples1.ts, 242, 20)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +type T28 = Last; +>T28 : Symbol(T28, Decl(variadicTuples1.ts, 249, 20)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T29 = Last; ->T29 : Symbol(T29, Decl(variadicTuples1.ts, 243, 21)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>T29 : Symbol(T29, Decl(variadicTuples1.ts, 250, 21)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type T30 = DropLast<[number, symbol, string]>; ->T30 : Symbol(T30, Decl(variadicTuples1.ts, 244, 23)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T30 : Symbol(T30, Decl(variadicTuples1.ts, 251, 23)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T31 = DropLast<[symbol, string]>; ->T31 : Symbol(T31, Decl(variadicTuples1.ts, 246, 46)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T31 : Symbol(T31, Decl(variadicTuples1.ts, 253, 46)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T32 = DropLast<[string]>; ->T32 : Symbol(T32, Decl(variadicTuples1.ts, 247, 38)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T32 : Symbol(T32, Decl(variadicTuples1.ts, 254, 38)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T33 = DropLast<[number, symbol, ...string[]]>; ->T33 : Symbol(T33, Decl(variadicTuples1.ts, 248, 30)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T33 : Symbol(T33, Decl(variadicTuples1.ts, 255, 30)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T34 = DropLast<[symbol, ...string[]]>; ->T34 : Symbol(T34, Decl(variadicTuples1.ts, 249, 51)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T34 : Symbol(T34, Decl(variadicTuples1.ts, 256, 51)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T35 = DropLast<[string?]>; ->T35 : Symbol(T35, Decl(variadicTuples1.ts, 250, 43)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T35 : Symbol(T35, Decl(variadicTuples1.ts, 257, 43)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T36 = DropLast; ->T36 : Symbol(T36, Decl(variadicTuples1.ts, 251, 31)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T36 : Symbol(T36, Decl(variadicTuples1.ts, 258, 31)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T37 = DropLast<[]>; // unknown[], maybe should be [] ->T37 : Symbol(T37, Decl(variadicTuples1.ts, 252, 30)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T37 : Symbol(T37, Decl(variadicTuples1.ts, 259, 30)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T38 = DropLast; ->T38 : Symbol(T38, Decl(variadicTuples1.ts, 253, 24)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T38 : Symbol(T38, Decl(variadicTuples1.ts, 260, 24)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type T39 = DropLast; ->T39 : Symbol(T39, Decl(variadicTuples1.ts, 254, 25)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>T39 : Symbol(T39, Decl(variadicTuples1.ts, 261, 25)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R00 = First; ->R00 : Symbol(R00, Decl(variadicTuples1.ts, 255, 27)) +>R00 : Symbol(R00, Decl(variadicTuples1.ts, 262, 27)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R01 = First; ->R01 : Symbol(R01, Decl(variadicTuples1.ts, 257, 52)) +>R01 : Symbol(R01, Decl(variadicTuples1.ts, 264, 52)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R02 = First; ->R02 : Symbol(R02, Decl(variadicTuples1.ts, 258, 44)) +>R02 : Symbol(R02, Decl(variadicTuples1.ts, 265, 44)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R03 = First; ->R03 : Symbol(R03, Decl(variadicTuples1.ts, 259, 36)) +>R03 : Symbol(R03, Decl(variadicTuples1.ts, 266, 36)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R04 = First; ->R04 : Symbol(R04, Decl(variadicTuples1.ts, 260, 57)) +>R04 : Symbol(R04, Decl(variadicTuples1.ts, 267, 57)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R05 = First; ->R05 : Symbol(R05, Decl(variadicTuples1.ts, 261, 49)) +>R05 : Symbol(R05, Decl(variadicTuples1.ts, 268, 49)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R06 = First; ->R06 : Symbol(R06, Decl(variadicTuples1.ts, 262, 36)) +>R06 : Symbol(R06, Decl(variadicTuples1.ts, 269, 36)) >First : Symbol(First, Decl(variadicTuples1.ts, 203, 1)) type R10 = DropFirst; ->R10 : Symbol(R10, Decl(variadicTuples1.ts, 263, 30)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R10 : Symbol(R10, Decl(variadicTuples1.ts, 270, 30)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R11 = DropFirst; ->R11 : Symbol(R11, Decl(variadicTuples1.ts, 265, 56)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R11 : Symbol(R11, Decl(variadicTuples1.ts, 272, 56)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R12 = DropFirst; ->R12 : Symbol(R12, Decl(variadicTuples1.ts, 266, 48)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R12 : Symbol(R12, Decl(variadicTuples1.ts, 273, 48)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R13 = DropFirst; ->R13 : Symbol(R13, Decl(variadicTuples1.ts, 267, 40)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R13 : Symbol(R13, Decl(variadicTuples1.ts, 274, 40)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R14 = DropFirst; ->R14 : Symbol(R14, Decl(variadicTuples1.ts, 268, 61)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R14 : Symbol(R14, Decl(variadicTuples1.ts, 275, 61)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R15 = DropFirst; ->R15 : Symbol(R15, Decl(variadicTuples1.ts, 269, 53)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R15 : Symbol(R15, Decl(variadicTuples1.ts, 276, 53)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R16 = DropFirst; ->R16 : Symbol(R16, Decl(variadicTuples1.ts, 270, 40)) ->DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 207, 48)) +>R16 : Symbol(R16, Decl(variadicTuples1.ts, 277, 40)) +>DropFirst : Symbol(DropFirst, Decl(variadicTuples1.ts, 209, 21)) type R20 = Last; ->R20 : Symbol(R20, Decl(variadicTuples1.ts, 271, 34)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R20 : Symbol(R20, Decl(variadicTuples1.ts, 278, 34)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R21 = Last; ->R21 : Symbol(R21, Decl(variadicTuples1.ts, 273, 51)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R21 : Symbol(R21, Decl(variadicTuples1.ts, 280, 51)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R22 = Last; ->R22 : Symbol(R22, Decl(variadicTuples1.ts, 274, 43)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R22 : Symbol(R22, Decl(variadicTuples1.ts, 281, 43)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R23 = Last; ->R23 : Symbol(R23, Decl(variadicTuples1.ts, 275, 35)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R23 : Symbol(R23, Decl(variadicTuples1.ts, 282, 35)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R24 = Last; ->R24 : Symbol(R24, Decl(variadicTuples1.ts, 276, 56)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R24 : Symbol(R24, Decl(variadicTuples1.ts, 283, 56)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R25 = Last; ->R25 : Symbol(R25, Decl(variadicTuples1.ts, 277, 48)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R25 : Symbol(R25, Decl(variadicTuples1.ts, 284, 48)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R26 = Last; ->R26 : Symbol(R26, Decl(variadicTuples1.ts, 278, 35)) ->Last : Symbol(Last, Decl(variadicTuples1.ts, 208, 98)) +>R26 : Symbol(R26, Decl(variadicTuples1.ts, 285, 35)) +>Last : Symbol(Last, Decl(variadicTuples1.ts, 211, 102)) type R30 = DropLast; ->R30 : Symbol(R30, Decl(variadicTuples1.ts, 279, 29)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R30 : Symbol(R30, Decl(variadicTuples1.ts, 286, 29)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R31 = DropLast; ->R31 : Symbol(R31, Decl(variadicTuples1.ts, 281, 55)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R31 : Symbol(R31, Decl(variadicTuples1.ts, 288, 55)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R32 = DropLast; ->R32 : Symbol(R32, Decl(variadicTuples1.ts, 282, 47)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R32 : Symbol(R32, Decl(variadicTuples1.ts, 289, 47)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R33 = DropLast; ->R33 : Symbol(R33, Decl(variadicTuples1.ts, 283, 39)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R33 : Symbol(R33, Decl(variadicTuples1.ts, 290, 39)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R34 = DropLast; ->R34 : Symbol(R34, Decl(variadicTuples1.ts, 284, 60)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R34 : Symbol(R34, Decl(variadicTuples1.ts, 291, 60)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R35 = DropLast; ->R35 : Symbol(R35, Decl(variadicTuples1.ts, 285, 52)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R35 : Symbol(R35, Decl(variadicTuples1.ts, 292, 52)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) type R36 = DropLast; ->R36 : Symbol(R36, Decl(variadicTuples1.ts, 286, 39)) ->DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 210, 161)) +>R36 : Symbol(R36, Decl(variadicTuples1.ts, 293, 39)) +>DropLast : Symbol(DropLast, Decl(variadicTuples1.ts, 216, 26)) // Inference to [...T, ...U] with implied arity for T function curry(f: (...args: [...T, ...U]) => R, ...a: T) { ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->T : Symbol(T, Decl(variadicTuples1.ts, 291, 15)) ->U : Symbol(U, Decl(variadicTuples1.ts, 291, 35)) ->R : Symbol(R, Decl(variadicTuples1.ts, 291, 56)) ->f : Symbol(f, Decl(variadicTuples1.ts, 291, 60)) ->args : Symbol(args, Decl(variadicTuples1.ts, 291, 64)) ->T : Symbol(T, Decl(variadicTuples1.ts, 291, 15)) ->U : Symbol(U, Decl(variadicTuples1.ts, 291, 35)) ->R : Symbol(R, Decl(variadicTuples1.ts, 291, 56)) ->a : Symbol(a, Decl(variadicTuples1.ts, 291, 92)) ->T : Symbol(T, Decl(variadicTuples1.ts, 291, 15)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>T : Symbol(T, Decl(variadicTuples1.ts, 298, 15)) +>U : Symbol(U, Decl(variadicTuples1.ts, 298, 35)) +>R : Symbol(R, Decl(variadicTuples1.ts, 298, 56)) +>f : Symbol(f, Decl(variadicTuples1.ts, 298, 60)) +>args : Symbol(args, Decl(variadicTuples1.ts, 298, 64)) +>T : Symbol(T, Decl(variadicTuples1.ts, 298, 15)) +>U : Symbol(U, Decl(variadicTuples1.ts, 298, 35)) +>R : Symbol(R, Decl(variadicTuples1.ts, 298, 56)) +>a : Symbol(a, Decl(variadicTuples1.ts, 298, 92)) +>T : Symbol(T, Decl(variadicTuples1.ts, 298, 15)) return (...b: U) => f(...a, ...b); ->b : Symbol(b, Decl(variadicTuples1.ts, 292, 12)) ->U : Symbol(U, Decl(variadicTuples1.ts, 291, 35)) ->f : Symbol(f, Decl(variadicTuples1.ts, 291, 60)) ->a : Symbol(a, Decl(variadicTuples1.ts, 291, 92)) ->b : Symbol(b, Decl(variadicTuples1.ts, 292, 12)) +>b : Symbol(b, Decl(variadicTuples1.ts, 299, 12)) +>U : Symbol(U, Decl(variadicTuples1.ts, 298, 35)) +>f : Symbol(f, Decl(variadicTuples1.ts, 298, 60)) +>a : Symbol(a, Decl(variadicTuples1.ts, 298, 92)) +>b : Symbol(b, Decl(variadicTuples1.ts, 299, 12)) } const fn1 = (a: number, b: string, c: boolean, d: string[]) => 0; ->fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 295, 5)) ->a : Symbol(a, Decl(variadicTuples1.ts, 295, 13)) ->b : Symbol(b, Decl(variadicTuples1.ts, 295, 23)) ->c : Symbol(c, Decl(variadicTuples1.ts, 295, 34)) ->d : Symbol(d, Decl(variadicTuples1.ts, 295, 46)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 302, 5)) +>a : Symbol(a, Decl(variadicTuples1.ts, 302, 13)) +>b : Symbol(b, Decl(variadicTuples1.ts, 302, 23)) +>c : Symbol(c, Decl(variadicTuples1.ts, 302, 34)) +>d : Symbol(d, Decl(variadicTuples1.ts, 302, 46)) const c0 = curry(fn1); // (a: number, b: string, c: boolean, d: string[]) => number ->c0 : Symbol(c0, Decl(variadicTuples1.ts, 297, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 295, 5)) +>c0 : Symbol(c0, Decl(variadicTuples1.ts, 304, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 302, 5)) const c1 = curry(fn1, 1); // (b: string, c: boolean, d: string[]) => number ->c1 : Symbol(c1, Decl(variadicTuples1.ts, 298, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 295, 5)) +>c1 : Symbol(c1, Decl(variadicTuples1.ts, 305, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 302, 5)) const c2 = curry(fn1, 1, 'abc'); // (c: boolean, d: string[]) => number ->c2 : Symbol(c2, Decl(variadicTuples1.ts, 299, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 295, 5)) +>c2 : Symbol(c2, Decl(variadicTuples1.ts, 306, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 302, 5)) const c3 = curry(fn1, 1, 'abc', true); // (d: string[]) => number ->c3 : Symbol(c3, Decl(variadicTuples1.ts, 300, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 295, 5)) +>c3 : Symbol(c3, Decl(variadicTuples1.ts, 307, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 302, 5)) const c4 = curry(fn1, 1, 'abc', true, ['x', 'y']); // () => number ->c4 : Symbol(c4, Decl(variadicTuples1.ts, 301, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 295, 5)) +>c4 : Symbol(c4, Decl(variadicTuples1.ts, 308, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn1 : Symbol(fn1, Decl(variadicTuples1.ts, 302, 5)) const fn2 = (x: number, b: boolean, ...args: string[]) => 0; ->fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 303, 5)) ->x : Symbol(x, Decl(variadicTuples1.ts, 303, 13)) ->b : Symbol(b, Decl(variadicTuples1.ts, 303, 23)) ->args : Symbol(args, Decl(variadicTuples1.ts, 303, 35)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 310, 5)) +>x : Symbol(x, Decl(variadicTuples1.ts, 310, 13)) +>b : Symbol(b, Decl(variadicTuples1.ts, 310, 23)) +>args : Symbol(args, Decl(variadicTuples1.ts, 310, 35)) const c10 = curry(fn2); // (x: number, b: boolean, ...args: string[]) => number ->c10 : Symbol(c10, Decl(variadicTuples1.ts, 305, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 303, 5)) +>c10 : Symbol(c10, Decl(variadicTuples1.ts, 312, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 310, 5)) const c11 = curry(fn2, 1); // (b: boolean, ...args: string[]) => number ->c11 : Symbol(c11, Decl(variadicTuples1.ts, 306, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 303, 5)) +>c11 : Symbol(c11, Decl(variadicTuples1.ts, 313, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 310, 5)) const c12 = curry(fn2, 1, true); // (...args: string[]) => number ->c12 : Symbol(c12, Decl(variadicTuples1.ts, 307, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 303, 5)) +>c12 : Symbol(c12, Decl(variadicTuples1.ts, 314, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 310, 5)) const c13 = curry(fn2, 1, true, 'abc', 'def'); // (...args: string[]) => number ->c13 : Symbol(c13, Decl(variadicTuples1.ts, 308, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 303, 5)) +>c13 : Symbol(c13, Decl(variadicTuples1.ts, 315, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn2 : Symbol(fn2, Decl(variadicTuples1.ts, 310, 5)) const fn3 = (...args: string[]) => 0; ->fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 310, 5)) ->args : Symbol(args, Decl(variadicTuples1.ts, 310, 13)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 317, 5)) +>args : Symbol(args, Decl(variadicTuples1.ts, 317, 13)) const c20 = curry(fn3); // (...args: string[]) => number ->c20 : Symbol(c20, Decl(variadicTuples1.ts, 312, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 310, 5)) +>c20 : Symbol(c20, Decl(variadicTuples1.ts, 319, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 317, 5)) const c21 = curry(fn3, 'abc', 'def'); // (...args: string[]) => number ->c21 : Symbol(c21, Decl(variadicTuples1.ts, 313, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 310, 5)) +>c21 : Symbol(c21, Decl(variadicTuples1.ts, 320, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 317, 5)) const c22 = curry(fn3, ...sa); // (...args: string[]) => number ->c22 : Symbol(c22, Decl(variadicTuples1.ts, 314, 5)) ->curry : Symbol(curry, Decl(variadicTuples1.ts, 287, 33)) ->fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 310, 5)) +>c22 : Symbol(c22, Decl(variadicTuples1.ts, 321, 5)) +>curry : Symbol(curry, Decl(variadicTuples1.ts, 294, 33)) +>fn3 : Symbol(fn3, Decl(variadicTuples1.ts, 317, 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, 314, 30)) ->T : Symbol(T, Decl(variadicTuples1.ts, 318, 16)) ->U : Symbol(U, Decl(variadicTuples1.ts, 318, 36)) ->R : Symbol(R, Decl(variadicTuples1.ts, 318, 57)) ->f : Symbol(f, Decl(variadicTuples1.ts, 318, 61)) ->args : Symbol(args, Decl(variadicTuples1.ts, 318, 65)) ->T : Symbol(T, Decl(variadicTuples1.ts, 318, 16)) ->U : Symbol(U, Decl(variadicTuples1.ts, 318, 36)) ->R : Symbol(R, Decl(variadicTuples1.ts, 318, 57)) ->t : Symbol(t, Decl(variadicTuples1.ts, 318, 93)) ->T : Symbol(T, Decl(variadicTuples1.ts, 318, 16)) ->u : Symbol(u, Decl(variadicTuples1.ts, 318, 104)) ->U : Symbol(U, Decl(variadicTuples1.ts, 318, 36)) +>curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 321, 30)) +>T : Symbol(T, Decl(variadicTuples1.ts, 325, 16)) +>U : Symbol(U, Decl(variadicTuples1.ts, 325, 36)) +>R : Symbol(R, Decl(variadicTuples1.ts, 325, 57)) +>f : Symbol(f, Decl(variadicTuples1.ts, 325, 61)) +>args : Symbol(args, Decl(variadicTuples1.ts, 325, 65)) +>T : Symbol(T, Decl(variadicTuples1.ts, 325, 16)) +>U : Symbol(U, Decl(variadicTuples1.ts, 325, 36)) +>R : Symbol(R, Decl(variadicTuples1.ts, 325, 57)) +>t : Symbol(t, Decl(variadicTuples1.ts, 325, 93)) +>T : Symbol(T, Decl(variadicTuples1.ts, 325, 16)) +>u : Symbol(u, Decl(variadicTuples1.ts, 325, 104)) +>U : Symbol(U, Decl(variadicTuples1.ts, 325, 36)) return f(...t, ...u); ->f : Symbol(f, Decl(variadicTuples1.ts, 318, 61)) ->t : Symbol(t, Decl(variadicTuples1.ts, 318, 93)) ->u : Symbol(u, Decl(variadicTuples1.ts, 318, 104)) +>f : Symbol(f, Decl(variadicTuples1.ts, 325, 61)) +>t : Symbol(t, Decl(variadicTuples1.ts, 325, 93)) +>u : Symbol(u, Decl(variadicTuples1.ts, 325, 104)) } declare function fn10(a: string, b: number, c: boolean): string[]; ->fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 320, 1)) ->a : Symbol(a, Decl(variadicTuples1.ts, 322, 22)) ->b : Symbol(b, Decl(variadicTuples1.ts, 322, 32)) ->c : Symbol(c, Decl(variadicTuples1.ts, 322, 43)) +>fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 327, 1)) +>a : Symbol(a, Decl(variadicTuples1.ts, 329, 22)) +>b : Symbol(b, Decl(variadicTuples1.ts, 329, 32)) +>c : Symbol(c, Decl(variadicTuples1.ts, 329, 43)) curry2(fn10, ['hello', 42], [true]); ->curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 314, 30)) ->fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 320, 1)) +>curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 321, 30)) +>fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 327, 1)) curry2(fn10, ['hello'], [42, true]); ->curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 314, 30)) ->fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 320, 1)) +>curry2 : Symbol(curry2, Decl(variadicTuples1.ts, 321, 30)) +>fn10 : Symbol(fn10, Decl(variadicTuples1.ts, 327, 1)) // Inference to [...T] has higher priority than inference to [...T, number?] declare function ft(t1: [...T], t2: [...T, number?]): T; ->ft : Symbol(ft, Decl(variadicTuples1.ts, 325, 36)) ->T : Symbol(T, Decl(variadicTuples1.ts, 329, 20)) ->t1 : Symbol(t1, Decl(variadicTuples1.ts, 329, 41)) ->T : Symbol(T, Decl(variadicTuples1.ts, 329, 20)) ->t2 : Symbol(t2, Decl(variadicTuples1.ts, 329, 52)) ->T : Symbol(T, Decl(variadicTuples1.ts, 329, 20)) ->T : Symbol(T, Decl(variadicTuples1.ts, 329, 20)) +>ft : Symbol(ft, Decl(variadicTuples1.ts, 332, 36)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 20)) +>t1 : Symbol(t1, Decl(variadicTuples1.ts, 336, 41)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 20)) +>t2 : Symbol(t2, Decl(variadicTuples1.ts, 336, 52)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 20)) +>T : Symbol(T, Decl(variadicTuples1.ts, 336, 20)) ft([1, 2, 3], [1, 2, 3]); ->ft : Symbol(ft, Decl(variadicTuples1.ts, 325, 36)) +>ft : Symbol(ft, Decl(variadicTuples1.ts, 332, 36)) ft([1, 2], [1, 2, 3]); ->ft : Symbol(ft, Decl(variadicTuples1.ts, 325, 36)) +>ft : Symbol(ft, Decl(variadicTuples1.ts, 332, 36)) ft(['a', 'b'], ['c', 'd']) ->ft : Symbol(ft, Decl(variadicTuples1.ts, 325, 36)) +>ft : Symbol(ft, Decl(variadicTuples1.ts, 332, 36)) ft(['a', 'b'], ['c', 'd', 42]) ->ft : Symbol(ft, Decl(variadicTuples1.ts, 325, 36)) +>ft : Symbol(ft, Decl(variadicTuples1.ts, 332, 36)) // Last argument is contextually typed declare function call(...args: [...T, (...args: T) => R]): [T, R]; ->call : Symbol(call, Decl(variadicTuples1.ts, 334, 30)) ->T : Symbol(T, Decl(variadicTuples1.ts, 338, 22)) ->R : Symbol(R, Decl(variadicTuples1.ts, 338, 42)) ->args : Symbol(args, Decl(variadicTuples1.ts, 338, 46)) ->T : Symbol(T, Decl(variadicTuples1.ts, 338, 22)) ->args : Symbol(args, Decl(variadicTuples1.ts, 338, 63)) ->T : Symbol(T, Decl(variadicTuples1.ts, 338, 22)) ->R : Symbol(R, Decl(variadicTuples1.ts, 338, 42)) ->T : Symbol(T, Decl(variadicTuples1.ts, 338, 22)) ->R : Symbol(R, Decl(variadicTuples1.ts, 338, 42)) +>call : Symbol(call, Decl(variadicTuples1.ts, 341, 30)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 22)) +>R : Symbol(R, Decl(variadicTuples1.ts, 345, 42)) +>args : Symbol(args, Decl(variadicTuples1.ts, 345, 46)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 22)) +>args : Symbol(args, Decl(variadicTuples1.ts, 345, 63)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 22)) +>R : Symbol(R, Decl(variadicTuples1.ts, 345, 42)) +>T : Symbol(T, Decl(variadicTuples1.ts, 345, 22)) +>R : Symbol(R, Decl(variadicTuples1.ts, 345, 42)) call('hello', 32, (a, b) => 42); ->call : Symbol(call, Decl(variadicTuples1.ts, 334, 30)) ->a : Symbol(a, Decl(variadicTuples1.ts, 340, 19)) ->b : Symbol(b, Decl(variadicTuples1.ts, 340, 21)) - -// Would be nice to infer [...string[], (...args: string[]) => number] here -// Requires [starting-fixed-part, ...rest-part, ending-fixed-part] tuple structure +>call : Symbol(call, Decl(variadicTuples1.ts, 341, 30)) +>a : Symbol(a, Decl(variadicTuples1.ts, 347, 19)) +>b : Symbol(b, Decl(variadicTuples1.ts, 347, 21)) call(...sa, (...x) => 42); ->call : Symbol(call, Decl(variadicTuples1.ts, 334, 30)) +>call : Symbol(call, Decl(variadicTuples1.ts, 341, 30)) >sa : Symbol(sa, Decl(variadicTuples1.ts, 29, 13)) ->x : Symbol(x, Decl(variadicTuples1.ts, 345, 13)) +>x : Symbol(x, Decl(variadicTuples1.ts, 348, 13)) // No inference to ending optional elements (except with identical structure) declare function f20(args: [...T, number?]): T; ->f20 : Symbol(f20, Decl(variadicTuples1.ts, 345, 26)) ->T : Symbol(T, Decl(variadicTuples1.ts, 349, 21)) ->args : Symbol(args, Decl(variadicTuples1.ts, 349, 47)) ->T : Symbol(T, Decl(variadicTuples1.ts, 349, 21)) ->T : Symbol(T, Decl(variadicTuples1.ts, 349, 21)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 348, 26)) +>T : Symbol(T, Decl(variadicTuples1.ts, 352, 21)) +>args : Symbol(args, Decl(variadicTuples1.ts, 352, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 352, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 352, 21)) function f21(args: [...U, number?]) { ->f21 : Symbol(f21, Decl(variadicTuples1.ts, 349, 73)) ->U : Symbol(U, Decl(variadicTuples1.ts, 351, 13)) ->args : Symbol(args, Decl(variadicTuples1.ts, 351, 33)) ->U : Symbol(U, Decl(variadicTuples1.ts, 351, 13)) +>f21 : Symbol(f21, Decl(variadicTuples1.ts, 352, 73)) +>U : Symbol(U, Decl(variadicTuples1.ts, 354, 13)) +>args : Symbol(args, Decl(variadicTuples1.ts, 354, 33)) +>U : Symbol(U, Decl(variadicTuples1.ts, 354, 13)) let v1 = f20(args); // U ->v1 : Symbol(v1, Decl(variadicTuples1.ts, 352, 7)) ->f20 : Symbol(f20, Decl(variadicTuples1.ts, 345, 26)) ->args : Symbol(args, Decl(variadicTuples1.ts, 351, 33)) +>v1 : Symbol(v1, Decl(variadicTuples1.ts, 355, 7)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 348, 26)) +>args : Symbol(args, Decl(variadicTuples1.ts, 354, 33)) let v2 = f20(["foo", "bar"]); // [string] ->v2 : Symbol(v2, Decl(variadicTuples1.ts, 353, 7)) ->f20 : Symbol(f20, Decl(variadicTuples1.ts, 345, 26)) +>v2 : Symbol(v2, Decl(variadicTuples1.ts, 356, 7)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 348, 26)) let v3 = f20(["foo", 42]); // [string] ->v3 : Symbol(v3, Decl(variadicTuples1.ts, 354, 7)) ->f20 : Symbol(f20, Decl(variadicTuples1.ts, 345, 26)) +>v3 : Symbol(v3, Decl(variadicTuples1.ts, 357, 7)) +>f20 : Symbol(f20, Decl(variadicTuples1.ts, 348, 26)) } declare function f22(args: [...T, number]): T; ->f22 : Symbol(f22, Decl(variadicTuples1.ts, 355, 1), Decl(variadicTuples1.ts, 357, 72)) ->T : Symbol(T, Decl(variadicTuples1.ts, 357, 21)) ->args : Symbol(args, Decl(variadicTuples1.ts, 357, 47)) ->T : Symbol(T, Decl(variadicTuples1.ts, 357, 21)) ->T : Symbol(T, Decl(variadicTuples1.ts, 357, 21)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 358, 1), Decl(variadicTuples1.ts, 360, 72)) +>T : Symbol(T, Decl(variadicTuples1.ts, 360, 21)) +>args : Symbol(args, Decl(variadicTuples1.ts, 360, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 360, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 360, 21)) declare function f22(args: [...T]): T; ->f22 : Symbol(f22, Decl(variadicTuples1.ts, 355, 1), Decl(variadicTuples1.ts, 357, 72)) ->T : Symbol(T, Decl(variadicTuples1.ts, 358, 21)) ->args : Symbol(args, Decl(variadicTuples1.ts, 358, 47)) ->T : Symbol(T, Decl(variadicTuples1.ts, 358, 21)) ->T : Symbol(T, Decl(variadicTuples1.ts, 358, 21)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 358, 1), Decl(variadicTuples1.ts, 360, 72)) +>T : Symbol(T, Decl(variadicTuples1.ts, 361, 21)) +>args : Symbol(args, Decl(variadicTuples1.ts, 361, 47)) +>T : Symbol(T, Decl(variadicTuples1.ts, 361, 21)) +>T : Symbol(T, Decl(variadicTuples1.ts, 361, 21)) function f23(args: [...U, number]) { ->f23 : Symbol(f23, Decl(variadicTuples1.ts, 358, 64)) ->U : Symbol(U, Decl(variadicTuples1.ts, 360, 13)) ->args : Symbol(args, Decl(variadicTuples1.ts, 360, 33)) ->U : Symbol(U, Decl(variadicTuples1.ts, 360, 13)) +>f23 : Symbol(f23, Decl(variadicTuples1.ts, 361, 64)) +>U : Symbol(U, Decl(variadicTuples1.ts, 363, 13)) +>args : Symbol(args, Decl(variadicTuples1.ts, 363, 33)) +>U : Symbol(U, Decl(variadicTuples1.ts, 363, 13)) let v1 = f22(args); // U ->v1 : Symbol(v1, Decl(variadicTuples1.ts, 361, 7)) ->f22 : Symbol(f22, Decl(variadicTuples1.ts, 355, 1), Decl(variadicTuples1.ts, 357, 72)) ->args : Symbol(args, Decl(variadicTuples1.ts, 360, 33)) +>v1 : Symbol(v1, Decl(variadicTuples1.ts, 364, 7)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 358, 1), Decl(variadicTuples1.ts, 360, 72)) +>args : Symbol(args, Decl(variadicTuples1.ts, 363, 33)) let v2 = f22(["foo", "bar"]); // [string, string] ->v2 : Symbol(v2, Decl(variadicTuples1.ts, 362, 7)) ->f22 : Symbol(f22, Decl(variadicTuples1.ts, 355, 1), Decl(variadicTuples1.ts, 357, 72)) +>v2 : Symbol(v2, Decl(variadicTuples1.ts, 365, 7)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 358, 1), Decl(variadicTuples1.ts, 360, 72)) let v3 = f22(["foo", 42]); // [string] ->v3 : Symbol(v3, Decl(variadicTuples1.ts, 363, 7)) ->f22 : Symbol(f22, Decl(variadicTuples1.ts, 355, 1), Decl(variadicTuples1.ts, 357, 72)) +>v3 : Symbol(v3, Decl(variadicTuples1.ts, 366, 7)) +>f22 : Symbol(f22, Decl(variadicTuples1.ts, 358, 1), Decl(variadicTuples1.ts, 360, 72)) } // Repro from #39327 interface Desc { ->Desc : Symbol(Desc, Decl(variadicTuples1.ts, 364, 1)) ->A : Symbol(A, Decl(variadicTuples1.ts, 368, 15)) ->T : Symbol(T, Decl(variadicTuples1.ts, 368, 35)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 367, 1)) +>A : Symbol(A, Decl(variadicTuples1.ts, 371, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 371, 35)) readonly f: (...args: A) => T; ->f : Symbol(Desc.f, Decl(variadicTuples1.ts, 368, 40)) ->args : Symbol(args, Decl(variadicTuples1.ts, 369, 17)) ->A : Symbol(A, Decl(variadicTuples1.ts, 368, 15)) ->T : Symbol(T, Decl(variadicTuples1.ts, 368, 35)) +>f : Symbol(Desc.f, Decl(variadicTuples1.ts, 371, 40)) +>args : Symbol(args, Decl(variadicTuples1.ts, 372, 17)) +>A : Symbol(A, Decl(variadicTuples1.ts, 371, 15)) +>T : Symbol(T, Decl(variadicTuples1.ts, 371, 35)) bind(this: Desc<[...T, ...U], R>, ...args: T): Desc<[...U], R>; ->bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 369, 34)) ->T : Symbol(T, Decl(variadicTuples1.ts, 370, 9)) ->U : Symbol(U, Decl(variadicTuples1.ts, 370, 29)) ->R : Symbol(R, Decl(variadicTuples1.ts, 370, 50)) ->this : Symbol(this, Decl(variadicTuples1.ts, 370, 54)) ->Desc : Symbol(Desc, Decl(variadicTuples1.ts, 364, 1)) ->T : Symbol(T, Decl(variadicTuples1.ts, 370, 9)) ->U : Symbol(U, Decl(variadicTuples1.ts, 370, 29)) ->R : Symbol(R, Decl(variadicTuples1.ts, 370, 50)) ->args : Symbol(args, Decl(variadicTuples1.ts, 370, 82)) ->T : Symbol(T, Decl(variadicTuples1.ts, 370, 9)) ->Desc : Symbol(Desc, Decl(variadicTuples1.ts, 364, 1)) ->U : Symbol(U, Decl(variadicTuples1.ts, 370, 29)) ->R : Symbol(R, Decl(variadicTuples1.ts, 370, 50)) +>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 372, 34)) +>T : Symbol(T, Decl(variadicTuples1.ts, 373, 9)) +>U : Symbol(U, Decl(variadicTuples1.ts, 373, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 373, 50)) +>this : Symbol(this, Decl(variadicTuples1.ts, 373, 54)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 367, 1)) +>T : Symbol(T, Decl(variadicTuples1.ts, 373, 9)) +>U : Symbol(U, Decl(variadicTuples1.ts, 373, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 373, 50)) +>args : Symbol(args, Decl(variadicTuples1.ts, 373, 82)) +>T : Symbol(T, Decl(variadicTuples1.ts, 373, 9)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 367, 1)) +>U : Symbol(U, Decl(variadicTuples1.ts, 373, 29)) +>R : Symbol(R, Decl(variadicTuples1.ts, 373, 50)) } declare const a: Desc<[string, number, boolean], object>; ->a : Symbol(a, Decl(variadicTuples1.ts, 373, 13)) ->Desc : Symbol(Desc, Decl(variadicTuples1.ts, 364, 1)) +>a : Symbol(a, Decl(variadicTuples1.ts, 376, 13)) +>Desc : Symbol(Desc, Decl(variadicTuples1.ts, 367, 1)) const b = a.bind("", 1); // Desc<[boolean], object> ->b : Symbol(b, Decl(variadicTuples1.ts, 374, 5)) ->a.bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 369, 34)) ->a : Symbol(a, Decl(variadicTuples1.ts, 373, 13)) ->bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 369, 34)) +>b : Symbol(b, Decl(variadicTuples1.ts, 377, 5)) +>a.bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 372, 34)) +>a : Symbol(a, Decl(variadicTuples1.ts, 376, 13)) +>bind : Symbol(Desc.bind, Decl(variadicTuples1.ts, 372, 34)) // Repro from #39607 declare function getUser(id: string, options?: { x?: string }): string; ->getUser : Symbol(getUser, Decl(variadicTuples1.ts, 374, 24)) ->id : Symbol(id, Decl(variadicTuples1.ts, 378, 25)) ->options : Symbol(options, Decl(variadicTuples1.ts, 378, 36)) ->x : Symbol(x, Decl(variadicTuples1.ts, 378, 48)) +>getUser : Symbol(getUser, Decl(variadicTuples1.ts, 377, 24)) +>id : Symbol(id, Decl(variadicTuples1.ts, 381, 25)) +>options : Symbol(options, Decl(variadicTuples1.ts, 381, 36)) +>x : Symbol(x, Decl(variadicTuples1.ts, 381, 48)) declare function getOrgUser(id: string, orgId: number, options?: { y?: number, z?: boolean }): void; ->getOrgUser : Symbol(getOrgUser, Decl(variadicTuples1.ts, 378, 71)) ->id : Symbol(id, Decl(variadicTuples1.ts, 380, 28)) ->orgId : Symbol(orgId, Decl(variadicTuples1.ts, 380, 39)) ->options : Symbol(options, Decl(variadicTuples1.ts, 380, 54)) ->y : Symbol(y, Decl(variadicTuples1.ts, 380, 66)) ->z : Symbol(z, Decl(variadicTuples1.ts, 380, 78)) +>getOrgUser : Symbol(getOrgUser, Decl(variadicTuples1.ts, 381, 71)) +>id : Symbol(id, Decl(variadicTuples1.ts, 383, 28)) +>orgId : Symbol(orgId, Decl(variadicTuples1.ts, 383, 39)) +>options : Symbol(options, Decl(variadicTuples1.ts, 383, 54)) +>y : Symbol(y, Decl(variadicTuples1.ts, 383, 66)) +>z : Symbol(z, Decl(variadicTuples1.ts, 383, 78)) function callApi(method: (...args: [...T, object]) => U) { ->callApi : Symbol(callApi, Decl(variadicTuples1.ts, 380, 100)) ->T : Symbol(T, Decl(variadicTuples1.ts, 382, 17)) ->U : Symbol(U, Decl(variadicTuples1.ts, 382, 42)) ->method : Symbol(method, Decl(variadicTuples1.ts, 382, 53)) ->args : Symbol(args, Decl(variadicTuples1.ts, 382, 62)) ->T : Symbol(T, Decl(variadicTuples1.ts, 382, 17)) ->U : Symbol(U, Decl(variadicTuples1.ts, 382, 42)) +>callApi : Symbol(callApi, Decl(variadicTuples1.ts, 383, 100)) +>T : Symbol(T, Decl(variadicTuples1.ts, 385, 17)) +>U : Symbol(U, Decl(variadicTuples1.ts, 385, 42)) +>method : Symbol(method, Decl(variadicTuples1.ts, 385, 53)) +>args : Symbol(args, Decl(variadicTuples1.ts, 385, 62)) +>T : Symbol(T, Decl(variadicTuples1.ts, 385, 17)) +>U : Symbol(U, Decl(variadicTuples1.ts, 385, 42)) return (...args: [...T]) => method(...args, {}); ->args : Symbol(args, Decl(variadicTuples1.ts, 383, 12)) ->T : Symbol(T, Decl(variadicTuples1.ts, 382, 17)) ->method : Symbol(method, Decl(variadicTuples1.ts, 382, 53)) ->args : Symbol(args, Decl(variadicTuples1.ts, 383, 12)) +>args : Symbol(args, Decl(variadicTuples1.ts, 386, 12)) +>T : Symbol(T, Decl(variadicTuples1.ts, 385, 17)) +>method : Symbol(method, Decl(variadicTuples1.ts, 385, 53)) +>args : Symbol(args, Decl(variadicTuples1.ts, 386, 12)) } callApi(getUser); ->callApi : Symbol(callApi, Decl(variadicTuples1.ts, 380, 100)) ->getUser : Symbol(getUser, Decl(variadicTuples1.ts, 374, 24)) +>callApi : Symbol(callApi, Decl(variadicTuples1.ts, 383, 100)) +>getUser : Symbol(getUser, Decl(variadicTuples1.ts, 377, 24)) callApi(getOrgUser); ->callApi : Symbol(callApi, Decl(variadicTuples1.ts, 380, 100)) ->getOrgUser : Symbol(getOrgUser, Decl(variadicTuples1.ts, 378, 71)) +>callApi : Symbol(callApi, Decl(variadicTuples1.ts, 383, 100)) +>getOrgUser : Symbol(getOrgUser, Decl(variadicTuples1.ts, 381, 71)) // Repro from #40235 type Numbers = number[]; ->Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 387, 20)) +>Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 390, 20)) type Unbounded = [...Numbers, boolean]; ->Unbounded : Symbol(Unbounded, Decl(variadicTuples1.ts, 391, 24)) ->Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 387, 20)) +>Unbounded : Symbol(Unbounded, Decl(variadicTuples1.ts, 394, 24)) +>Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 390, 20)) -const data: Unbounded = [false, false]; ->data : Symbol(data, Decl(variadicTuples1.ts, 393, 5)) ->Unbounded : Symbol(Unbounded, Decl(variadicTuples1.ts, 391, 24)) +const data: Unbounded = [false, false]; // Error +>data : Symbol(data, Decl(variadicTuples1.ts, 396, 5)) +>Unbounded : Symbol(Unbounded, Decl(variadicTuples1.ts, 394, 24)) type U1 = [string, ...Numbers, boolean]; ->U1 : Symbol(U1, Decl(variadicTuples1.ts, 393, 39)) ->Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 387, 20)) +>U1 : Symbol(U1, Decl(variadicTuples1.ts, 396, 39)) +>Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 390, 20)) type U2 = [...[string, ...Numbers], boolean]; ->U2 : Symbol(U2, Decl(variadicTuples1.ts, 395, 40)) ->Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 387, 20)) +>U2 : Symbol(U2, Decl(variadicTuples1.ts, 398, 40)) +>Numbers : Symbol(Numbers, Decl(variadicTuples1.ts, 390, 20)) type U3 = [...[string, number], boolean]; ->U3 : Symbol(U3, Decl(variadicTuples1.ts, 396, 45)) +>U3 : Symbol(U3, Decl(variadicTuples1.ts, 399, 45)) diff --git a/tests/baselines/reference/variadicTuples1.types b/tests/baselines/reference/variadicTuples1.types index 255eefabc34df..3bb6d7d6d65c2 100644 --- a/tests/baselines/reference/variadicTuples1.types +++ b/tests/baselines/reference/variadicTuples1.types @@ -10,7 +10,7 @@ type TV1 = [string, ...T, number]; type TV2 = [string, ...T, number, ...T]; >TV2 : [string, ...T, number, ...T] -type TV3 = [string, ...T, ...number[], ...T]; // Error +type TV3 = [string, ...T, ...number[], ...T]; >TV3 : [string, ...T, ...number[], ...T] // Normalization @@ -772,16 +772,23 @@ function f15(k0: keyof T, k1: keyof [...T], k2: // Inference between variadic tuple types -type First = T[0]; +type First = >First : First -type DropFirst = T extends readonly [any?, ...infer U] ? U : [...T]; + T extends readonly [unknown, ...unknown[]] ? T[0] : + T[0] | undefined; + +type DropFirst = T extends readonly [unknown?, ...infer U] ? U : [...T]; >DropFirst : DropFirst -type Last = T extends readonly [...infer _, infer U] ? U : T extends readonly [...infer _, (infer U)?] ? U | undefined : undefined; +type Last = >Last : Last -type DropLast = T extends readonly [...infer U, any?] ? U : [...T]; + T extends readonly [...unknown[], infer U] ? U : + T extends readonly [unknown, ...unknown[]] ? T[number] : + T[number] | undefined; + +type DropLast = T extends readonly [...infer U, unknown] ? U : [...T]; >DropLast : DropLast type T00 = First<[number, symbol, string]>; @@ -803,7 +810,7 @@ type T05 = First<[string?]>; >T05 : string | undefined type T06 = First; ->T06 : string +>T06 : string | undefined type T07 = First<[]>; >T07 : undefined @@ -854,10 +861,10 @@ type T22 = Last<[string]>; >T22 : string type T23 = Last<[number, symbol, ...string[]]>; ->T23 : unknown +>T23 : string | number | symbol type T24 = Last<[symbol, ...string[]]>; ->T24 : unknown +>T24 : string | symbol type T25 = Last<[string?]>; >T25 : string | undefined @@ -865,11 +872,11 @@ type T25 = Last<[string?]>; type T26 = Last; >T26 : string | undefined -type T27 = Last<[]>; // unknown, maybe should undefined ->T27 : unknown +type T27 = Last<[]>; +>T27 : undefined -type T28 = Last; // unknown, maybe should be any ->T28 : unknown +type T28 = Last; +>T28 : any type T29 = Last; >T29 : never @@ -884,19 +891,19 @@ type T32 = DropLast<[string]>; >T32 : [] type T33 = DropLast<[number, symbol, ...string[]]>; ->T33 : unknown[] +>T33 : [number, symbol, ...string[]] type T34 = DropLast<[symbol, ...string[]]>; ->T34 : unknown[] +>T34 : [symbol, ...string[]] type T35 = DropLast<[string?]>; ->T35 : [] +>T35 : [(string | undefined)?] type T36 = DropLast; >T36 : string[] type T37 = DropLast<[]>; // unknown[], maybe should be [] ->T37 : unknown[] +>T37 : [] type T38 = DropLast; >T38 : unknown[] | any[] @@ -920,7 +927,7 @@ type R04 = First; >R04 : symbol type R05 = First; ->R05 : string +>R05 : string | undefined type R06 = First; >R06 : undefined @@ -956,16 +963,16 @@ type R22 = Last; >R22 : string type R23 = Last; ->R23 : unknown +>R23 : string | number | symbol type R24 = Last; ->R24 : unknown +>R24 : string | symbol type R25 = Last; >R25 : string | undefined type R26 = Last; ->R26 : unknown +>R26 : undefined type R30 = DropLast; >R30 : [number, symbol] @@ -977,16 +984,16 @@ type R32 = DropLast; >R32 : [] type R33 = DropLast; ->R33 : unknown[] +>R33 : [number, symbol, ...string[]] type R34 = DropLast; ->R34 : unknown[] +>R34 : [symbol, ...string[]] type R35 = DropLast; >R35 : string[] type R36 = DropLast; ->R36 : unknown[] +>R36 : [] // Inference to [...T, ...U] with implied arity for T @@ -1237,9 +1244,6 @@ call('hello', 32, (a, b) => 42); >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[], number] >call : (...args: [...T, (...args: T) => R]) => [T, R] @@ -1391,7 +1395,7 @@ type Numbers = number[]; type Unbounded = [...Numbers, boolean]; >Unbounded : [...number[], boolean] -const data: Unbounded = [false, false]; +const data: Unbounded = [false, false]; // Error >data : [...number[], boolean] >[false, false] : [false, false] >false : false diff --git a/tests/cases/conformance/types/tuple/variadicTuples1.ts b/tests/cases/conformance/types/tuple/variadicTuples1.ts index eeafb51510263..6860a3adc3aea 100644 --- a/tests/cases/conformance/types/tuple/variadicTuples1.ts +++ b/tests/cases/conformance/types/tuple/variadicTuples1.ts @@ -6,7 +6,7 @@ type TV0 = [string, ...T]; type TV1 = [string, ...T, number]; type TV2 = [string, ...T, number, ...T]; -type TV3 = [string, ...T, ...number[], ...T]; // Error +type TV3 = [string, ...T, ...number[], ...T]; // Normalization @@ -208,11 +208,18 @@ function f15(k0: keyof T, k1: keyof [...T], k2: // Inference between variadic tuple types -type First = T[0]; -type DropFirst = T extends readonly [any?, ...infer U] ? U : [...T]; +type First = + T extends readonly [unknown, ...unknown[]] ? T[0] : + T[0] | undefined; -type Last = T extends readonly [...infer _, infer U] ? U : T extends readonly [...infer _, (infer U)?] ? U | undefined : undefined; -type DropLast = T extends readonly [...infer U, any?] ? U : [...T]; +type DropFirst = T extends readonly [unknown?, ...infer U] ? U : [...T]; + +type Last = + T extends readonly [...unknown[], infer U] ? U : + T extends readonly [unknown, ...unknown[]] ? T[number] : + T[number] | undefined; + +type DropLast = T extends readonly [...infer U, unknown] ? U : [...T]; type T00 = First<[number, symbol, string]>; type T01 = First<[symbol, string]>; @@ -243,8 +250,8 @@ type T23 = Last<[number, symbol, ...string[]]>; type T24 = Last<[symbol, ...string[]]>; type T25 = Last<[string?]>; type T26 = Last; -type T27 = Last<[]>; // unknown, maybe should undefined -type T28 = Last; // unknown, maybe should be any +type T27 = Last<[]>; +type T28 = Last; type T29 = Last; type T30 = DropLast<[number, symbol, string]>; @@ -342,10 +349,6 @@ ft(['a', 'b'], ['c', 'd', 42]) 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); // No inference to ending optional elements (except with identical structure) @@ -394,7 +397,7 @@ callApi(getOrgUser); type Numbers = number[]; type Unbounded = [...Numbers, boolean]; -const data: Unbounded = [false, false]; +const data: Unbounded = [false, false]; // Error type U1 = [string, ...Numbers, boolean]; type U2 = [...[string, ...Numbers], boolean]; From 87d8b5b2b4be9a381c4753af51af8903b0732320 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Nov 2020 14:22:21 -0800 Subject: [PATCH 6/7] Add new tests --- .../reference/variadicTuples2.errors.txt | 294 ++++++++++ tests/baselines/reference/variadicTuples2.js | 268 +++++++++ .../reference/variadicTuples2.symbols | 404 +++++++++++++ .../baselines/reference/variadicTuples2.types | 538 ++++++++++++++++++ .../types/tuple/variadicTuples2.ts | 133 +++++ 5 files changed, 1637 insertions(+) create mode 100644 tests/baselines/reference/variadicTuples2.errors.txt create mode 100644 tests/baselines/reference/variadicTuples2.js create mode 100644 tests/baselines/reference/variadicTuples2.symbols create mode 100644 tests/baselines/reference/variadicTuples2.types create mode 100644 tests/cases/conformance/types/tuple/variadicTuples2.ts diff --git a/tests/baselines/reference/variadicTuples2.errors.txt b/tests/baselines/reference/variadicTuples2.errors.txt new file mode 100644 index 0000000000000..2947b3e1d57d9 --- /dev/null +++ b/tests/baselines/reference/variadicTuples2.errors.txt @@ -0,0 +1,294 @@ +tests/cases/conformance/types/tuple/variadicTuples2.ts(7,34): error TS1265: A rest element cannot follow another rest element. +tests/cases/conformance/types/tuple/variadicTuples2.ts(8,34): error TS1266: An optional element cannot follow a rest element. +tests/cases/conformance/types/tuple/variadicTuples2.ts(9,30): error TS1257: A required element cannot follow an optional element. +tests/cases/conformance/types/tuple/variadicTuples2.ts(42,1): error TS2322: Type '[string, string, number, number]' is not assignable to type '[...string[], number]'. + Type at positions 0 through 2 in source is not compatible with type at position 0 in target. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(48,5): error TS2345: Argument of type '["abc", "def", 5, 6]' is not assignable to parameter of type '[...strs: string[], num: number]'. + Type at positions 0 through 2 in source is not compatible with type at position 0 in target. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(51,1): error TS2322: Type '[number]' is not assignable to type '[number, ...string[], number]'. + Source has 1 element(s) but target requires 2. +tests/cases/conformance/types/tuple/variadicTuples2.ts(53,1): error TS2322: Type '[number, number, number]' is not assignable to type '[number, ...string[], number]'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(56,1): error TS2322: Type '[number, string, number, string]' is not assignable to type '[number, ...string[], number]'. + Type at positions 1 through 2 in source is not compatible with type at position 1 in target. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(57,8): error TS2322: Type 'boolean' is not assignable to type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(58,1): error TS2322: Type '[number, string, string, boolean]' is not assignable to type '[number, ...string[], number]'. + Type at position 3 in source is not compatible with type at position 2 in target. + Type 'boolean' is not assignable to type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(61,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[...strs: string[], n2: number]'. + Source has 0 element(s) but target requires 1. +tests/cases/conformance/types/tuple/variadicTuples2.ts(63,8): error TS2345: Argument of type '[1, 2]' is not assignable to parameter of type '[...strs: string[], n2: number]'. + Type at position 0 in source is not compatible with type at position 0 in target. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(66,8): error TS2345: Argument of type '["abc", 1, "def"]' is not assignable to parameter of type '[...strs: string[], n2: number]'. + Type at positions 0 through 1 in source is not compatible with type at position 0 in target. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(67,5): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(68,8): error TS2345: Argument of type '["abc", "def", true]' is not assignable to parameter of type '[...strs: string[], n2: number]'. + Type at position 2 in source is not compatible with type at position 1 in target. + Type 'boolean' is not assignable to type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(71,5): error TS2322: Type '[number, number]' is not assignable to type '[number, ...T]'. + Source provides no match for variadic element at position 1 in target. +tests/cases/conformance/types/tuple/variadicTuples2.ts(72,5): error TS2322: Type '[number, ...number[]]' is not assignable to type '[number, ...T]'. + Target requires 2 element(s) but source may have fewer. +tests/cases/conformance/types/tuple/variadicTuples2.ts(73,5): error TS2322: Type '[number, ...T]' is not assignable to type '[number, number]'. + Variadic element at position 1 in source does not match element at position 1 in target. +tests/cases/conformance/types/tuple/variadicTuples2.ts(74,5): error TS2322: Type '[number, ...T]' is not assignable to type '[number, ...number[]]'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'T[number]' is not assignable to type 'number'. + Type 'unknown' is not assignable to type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(107,16): error TS2345: Argument of type '[1, 2, 3, 4]' is not assignable to parameter of type '[...number[], (...values: number[]) => void]'. + Type at position 3 in source is not compatible with type at position 1 in target. + Type 'number' is not assignable to type '(...values: number[]) => void'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(108,6): error TS2345: Argument of type 'string[]' is not assignable to parameter of type '[...string[], (...values: string[]) => void]'. + Source provides no match for required element at position 1 in target. +tests/cases/conformance/types/tuple/variadicTuples2.ts(111,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. + Source has 0 element(s) but target requires 2. +tests/cases/conformance/types/tuple/variadicTuples2.ts(112,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. + Source has 1 element(s) but target requires 2. +tests/cases/conformance/types/tuple/variadicTuples2.ts(117,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. + Source has 0 element(s) but target requires 2. +tests/cases/conformance/types/tuple/variadicTuples2.ts(118,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. + Source has 1 element(s) but target requires 2. +tests/cases/conformance/types/tuple/variadicTuples2.ts(128,16): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(129,16): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Argument of type '["blah2", 1, 2, 3]' is not assignable to parameter of type '[...string[], number]'. + Type at positions 0 through 2 in source is not compatible with type at position 0 in target. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/types/tuple/variadicTuples2.ts (28 errors) ==== + // Declarations + + type V00 = [number, ...string[]]; + type V01 = [...string[], number]; + type V03 = [number, ...string[], number]; + + type V10 = [number, ...string[], ...boolean[]]; // Error + ~~~~~~~~~~~~ +!!! error TS1265: A rest element cannot follow another rest element. + type V11 = [number, ...string[], boolean?]; // Error + ~~~~~~~~ +!!! error TS1266: An optional element cannot follow a rest element. + type V12 = [number, string?, boolean]; // Error + ~~~~~~~ +!!! error TS1257: A required element cannot follow an optional element. + + // Normalization + + type Tup3 = [...T, ...U, ...V]; + + type V20 = Tup3<[number], string[], [number]>; // [number, ...string[], number] + type V21 = Tup3<[number], [string?], [boolean]>; // [number, string | undefined, boolean] + type V22 = Tup3<[number], string[], boolean[]>; // [number, (string | boolean)[]] + type V23 = Tup3<[number], string[], [boolean?]>; // [number, (string | boolean | undefined)[]] + type V24 = Tup3<[number], [boolean?], string[]>; // [number, boolean?, ...string[]] + type V25 = Tup3; // (string | number | boolean)[] + type V26 = Tup3; // [...(string | number)[], boolean] + type V27 = Tup3<[number?], [string], [boolean?]>; // [number | undefined, string, boolean?] + + type V30 = Tup3; // [...A, ...(string | number)[]] + type V31 = Tup3; // (string | number | A[number])[] + type V32 = Tup3; // [...(string | number)[], ...A] + + type V40 = Tup3; // [...A, string?, ...number[]] + type V41 = Tup3<[string?], A, number[]>; // [string?, ...A, ...number[]] + type V42 = Tup3<[string?], number[], A>; // [string?, ...number[], ...A] + + type V50 = Tup3; // [...A, ...(string | number | undefined)[]] + type V51 = Tup3; // (string | number | A[number] | undefined)[] + type V52 = Tup3; // [...(string | number | undefined)[], ...A] + + // Assignability + + declare let tt1: [...string[], number]; + tt1 = [5]; + tt1 = ['abc', 5]; + tt1 = ['abc', 'def', 5]; + tt1 = ['abc', 'def', 5, 6]; // Error + ~~~ +!!! error TS2322: Type '[string, string, number, number]' is not assignable to type '[...string[], number]'. +!!! error TS2322: Type at positions 0 through 2 in source is not compatible with type at position 0 in target. +!!! error TS2322: Type 'string | number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + declare function ft1(...args: [...strs: string[], num: number]): void; + ft1(5); + ft1('abc', 5); + ft1('abc', 'def', 5); + ft1('abc', 'def', 5, 6); // Error + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '["abc", "def", 5, 6]' is not assignable to parameter of type '[...strs: string[], num: number]'. +!!! error TS2345: Type at positions 0 through 2 in source is not compatible with type at position 0 in target. +!!! error TS2345: Type 'string | number' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + + declare let tt2: [number, ...string[], number]; + tt2 = [0]; // Error + ~~~ +!!! error TS2322: Type '[number]' is not assignable to type '[number, ...string[], number]'. +!!! error TS2322: Source has 1 element(s) but target requires 2. + tt2 = [0, 1]; + tt2 = [0, 1, 2]; // Error + ~~~ +!!! error TS2322: Type '[number, number, number]' is not assignable to type '[number, ...string[], number]'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + tt2 = [0, 'abc', 1]; + tt2 = [0, 'abc', 'def', 1]; + tt2 = [0, 'abc', 1, 'def']; // Error + ~~~ +!!! error TS2322: Type '[number, string, number, string]' is not assignable to type '[number, ...string[], number]'. +!!! error TS2322: Type at positions 1 through 2 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'string | number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + tt2 = [true, 'abc', 'def', 1]; // Error + ~~~~ +!!! error TS2322: Type 'boolean' is not assignable to type 'number'. + tt2 = [0, 'abc', 'def', true]; // Error + ~~~ +!!! error TS2322: Type '[number, string, string, boolean]' is not assignable to type '[number, ...string[], number]'. +!!! error TS2322: Type at position 3 in source is not compatible with type at position 2 in target. +!!! error TS2322: Type 'boolean' is not assignable to type 'number'. + + declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; + ft2(0); // Error + ~~~~~~ +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[...strs: string[], n2: number]'. +!!! error TS2345: Source has 0 element(s) but target requires 1. + ft2(0, 1); + ft2(0, 1, 2); // Error + ~~~~ +!!! error TS2345: Argument of type '[1, 2]' is not assignable to parameter of type '[...strs: string[], n2: number]'. +!!! error TS2345: Type at position 0 in source is not compatible with type at position 0 in target. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + ft2(0, 'abc', 1); + ft2(0, 'abc', 'def', 1); + ft2(0, 'abc', 1, 'def'); // Error + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '["abc", 1, "def"]' is not assignable to parameter of type '[...strs: string[], n2: number]'. +!!! error TS2345: Type at positions 0 through 1 in source is not compatible with type at position 0 in target. +!!! error TS2345: Type 'string | number' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + ft2(true, 'abc', 'def', 1); // Error + ~~~~ +!!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'number'. + ft2(0, 'abc', 'def', true); // Error + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '["abc", "def", true]' is not assignable to parameter of type '[...strs: string[], n2: number]'. +!!! error TS2345: Type at position 2 in source is not compatible with type at position 1 in target. +!!! error TS2345: Type 'boolean' is not assignable to type 'number'. + + function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]) { + x = y; // Error + ~ +!!! error TS2322: Type '[number, number]' is not assignable to type '[number, ...T]'. +!!! error TS2322: Source provides no match for variadic element at position 1 in target. + x = z; // Error + ~ +!!! error TS2322: Type '[number, ...number[]]' is not assignable to type '[number, ...T]'. +!!! error TS2322: Target requires 2 element(s) but source may have fewer. + y = x; // Error + ~ +!!! error TS2322: Type '[number, ...T]' is not assignable to type '[number, number]'. +!!! error TS2322: Variadic element at position 1 in source does not match element at position 1 in target. + z = x; // Error + ~ +!!! error TS2322: Type '[number, ...T]' is not assignable to type '[number, ...number[]]'. +!!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'T[number]' is not assignable to type 'number'. +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + } + + // Inference + + function pipe(...args: [...T, (...values: T) => void]) { + const callback = args[args.length - 1] as (...values: T) => void; + const values = args.slice(0, -1) as unknown as T; + callback(...values); + } + + pipe("foo", 123, true, (a, b, c) => { + a; // string + b; // number + c; // boolean + }) + + pipe("foo", 123, true, (...x) => { + x; // [string, number, boolean] + }); + + declare const sa: string[]; + + pipe(...sa, (...x) => { + x; // string[] + }); + + pipe(1, ...sa, 2, (...x) => { + x; // [number, ...string[], number] + let qq = x[x.length - 1]; + let ww = x[0] + }); + + pipe(1, 2, 3, 4); // Error + ~~~~~~~~~~ +!!! error TS2345: Argument of type '[1, 2, 3, 4]' is not assignable to parameter of type '[...number[], (...values: number[]) => void]'. +!!! error TS2345: Type at position 3 in source is not compatible with type at position 1 in target. +!!! error TS2345: Type 'number' is not assignable to type '(...values: number[]) => void'. + pipe(...sa); // Error + ~~~~~ +!!! error TS2345: Argument of type 'string[]' is not assignable to parameter of type '[...string[], (...values: string[]) => void]'. +!!! error TS2345: Source provides no match for required element at position 1 in target. + + declare function fn1(t: [...unknown[], T, U]): [T, U]; + fn1([]); // Error + ~~ +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. +!!! error TS2345: Source has 0 element(s) but target requires 2. + fn1([1]); // Error + ~~~ +!!! error TS2345: Argument of type '[number]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. +!!! error TS2345: Source has 1 element(s) but target requires 2. + fn1([1, 'abc']); // [number, string] + fn1([1, 'abc', true]); // [string, boolean] + + declare function fn2(t: [T, ...unknown[], U]): [T, U]; + fn2([]); // Error + ~~ +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. +!!! error TS2345: Source has 0 element(s) but target requires 2. + fn2([1]); // Error + ~~~ +!!! error TS2345: Argument of type '[number]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. +!!! error TS2345: Source has 1 element(s) but target requires 2. + fn2([1, 'abc']); // [number, string] + fn2([1, 'abc', true]); // [number, boolean] + + // Repro from #39595 + + declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; + + const a1 = foo('blah1', 1); + const b1 = foo('blah1', 'blah2', 1); + const c1 = foo(1); // Error + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + const d1 = foo(1, 2); // Error + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + const e1 = foo('blah1', 'blah2', 1, 2, 3); // Error + ~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '["blah2", 1, 2, 3]' is not assignable to parameter of type '[...string[], number]'. +!!! error TS2345: Type at positions 0 through 2 in source is not compatible with type at position 0 in target. +!!! error TS2345: Type 'string | number' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples2.js b/tests/baselines/reference/variadicTuples2.js new file mode 100644 index 0000000000000..95f1a6b721069 --- /dev/null +++ b/tests/baselines/reference/variadicTuples2.js @@ -0,0 +1,268 @@ +//// [variadicTuples2.ts] +// Declarations + +type V00 = [number, ...string[]]; +type V01 = [...string[], number]; +type V03 = [number, ...string[], number]; + +type V10 = [number, ...string[], ...boolean[]]; // Error +type V11 = [number, ...string[], boolean?]; // Error +type V12 = [number, string?, boolean]; // Error + +// Normalization + +type Tup3 = [...T, ...U, ...V]; + +type V20 = Tup3<[number], string[], [number]>; // [number, ...string[], number] +type V21 = Tup3<[number], [string?], [boolean]>; // [number, string | undefined, boolean] +type V22 = Tup3<[number], string[], boolean[]>; // [number, (string | boolean)[]] +type V23 = Tup3<[number], string[], [boolean?]>; // [number, (string | boolean | undefined)[]] +type V24 = Tup3<[number], [boolean?], string[]>; // [number, boolean?, ...string[]] +type V25 = Tup3; // (string | number | boolean)[] +type V26 = Tup3; // [...(string | number)[], boolean] +type V27 = Tup3<[number?], [string], [boolean?]>; // [number | undefined, string, boolean?] + +type V30 = Tup3; // [...A, ...(string | number)[]] +type V31 = Tup3; // (string | number | A[number])[] +type V32 = Tup3; // [...(string | number)[], ...A] + +type V40 = Tup3; // [...A, string?, ...number[]] +type V41 = Tup3<[string?], A, number[]>; // [string?, ...A, ...number[]] +type V42 = Tup3<[string?], number[], A>; // [string?, ...number[], ...A] + +type V50 = Tup3; // [...A, ...(string | number | undefined)[]] +type V51 = Tup3; // (string | number | A[number] | undefined)[] +type V52 = Tup3; // [...(string | number | undefined)[], ...A] + +// Assignability + +declare let tt1: [...string[], number]; +tt1 = [5]; +tt1 = ['abc', 5]; +tt1 = ['abc', 'def', 5]; +tt1 = ['abc', 'def', 5, 6]; // Error + +declare function ft1(...args: [...strs: string[], num: number]): void; +ft1(5); +ft1('abc', 5); +ft1('abc', 'def', 5); +ft1('abc', 'def', 5, 6); // Error + +declare let tt2: [number, ...string[], number]; +tt2 = [0]; // Error +tt2 = [0, 1]; +tt2 = [0, 1, 2]; // Error +tt2 = [0, 'abc', 1]; +tt2 = [0, 'abc', 'def', 1]; +tt2 = [0, 'abc', 1, 'def']; // Error +tt2 = [true, 'abc', 'def', 1]; // Error +tt2 = [0, 'abc', 'def', true]; // Error + +declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; +ft2(0); // Error +ft2(0, 1); +ft2(0, 1, 2); // Error +ft2(0, 'abc', 1); +ft2(0, 'abc', 'def', 1); +ft2(0, 'abc', 1, 'def'); // Error +ft2(true, 'abc', 'def', 1); // Error +ft2(0, 'abc', 'def', true); // Error + +function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]) { + x = y; // Error + x = z; // Error + y = x; // Error + z = x; // Error +} + +// Inference + +function pipe(...args: [...T, (...values: T) => void]) { + const callback = args[args.length - 1] as (...values: T) => void; + const values = args.slice(0, -1) as unknown as T; + callback(...values); +} + +pipe("foo", 123, true, (a, b, c) => { + a; // string + b; // number + c; // boolean +}) + +pipe("foo", 123, true, (...x) => { + x; // [string, number, boolean] +}); + +declare const sa: string[]; + +pipe(...sa, (...x) => { + x; // string[] +}); + +pipe(1, ...sa, 2, (...x) => { + x; // [number, ...string[], number] + let qq = x[x.length - 1]; + let ww = x[0] +}); + +pipe(1, 2, 3, 4); // Error +pipe(...sa); // Error + +declare function fn1(t: [...unknown[], T, U]): [T, U]; +fn1([]); // Error +fn1([1]); // Error +fn1([1, 'abc']); // [number, string] +fn1([1, 'abc', true]); // [string, boolean] + +declare function fn2(t: [T, ...unknown[], U]): [T, U]; +fn2([]); // Error +fn2([1]); // Error +fn2([1, 'abc']); // [number, string] +fn2([1, 'abc', true]); // [number, boolean] + +// Repro from #39595 + +declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; + +const a1 = foo('blah1', 1); +const b1 = foo('blah1', 'blah2', 1); +const c1 = foo(1); // Error +const d1 = foo(1, 2); // Error +const e1 = foo('blah1', 'blah2', 1, 2, 3); // Error + + +//// [variadicTuples2.js] +"use strict"; +// Declarations +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; +}; +tt1 = [5]; +tt1 = ['abc', 5]; +tt1 = ['abc', 'def', 5]; +tt1 = ['abc', 'def', 5, 6]; // Error +ft1(5); +ft1('abc', 5); +ft1('abc', 'def', 5); +ft1('abc', 'def', 5, 6); // Error +tt2 = [0]; // Error +tt2 = [0, 1]; +tt2 = [0, 1, 2]; // Error +tt2 = [0, 'abc', 1]; +tt2 = [0, 'abc', 'def', 1]; +tt2 = [0, 'abc', 1, 'def']; // Error +tt2 = [true, 'abc', 'def', 1]; // Error +tt2 = [0, 'abc', 'def', true]; // Error +ft2(0); // Error +ft2(0, 1); +ft2(0, 1, 2); // Error +ft2(0, 'abc', 1); +ft2(0, 'abc', 'def', 1); +ft2(0, 'abc', 1, 'def'); // Error +ft2(true, 'abc', 'def', 1); // Error +ft2(0, 'abc', 'def', true); // Error +function ft3(x, y, z) { + x = y; // Error + x = z; // Error + y = x; // Error + z = x; // Error +} +// Inference +function pipe() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var callback = args[args.length - 1]; + var values = args.slice(0, -1); + callback.apply(void 0, values); +} +pipe("foo", 123, true, function (a, b, c) { + a; // string + b; // number + c; // boolean +}); +pipe("foo", 123, true, function () { + var x = []; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i] = arguments[_i]; + } + x; // [string, number, boolean] +}); +pipe.apply(void 0, __spreadArrays(sa, [function () { + var x = []; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i] = arguments[_i]; + } + x; // string[] + }])); +pipe.apply(void 0, __spreadArrays([1], sa, [2, function () { + var x = []; + for (var _i = 0; _i < arguments.length; _i++) { + x[_i] = arguments[_i]; + } + x; // [number, ...string[], number] + var qq = x[x.length - 1]; + var ww = x[0]; + }])); +pipe(1, 2, 3, 4); // Error +pipe.apply(void 0, sa); // Error +fn1([]); // Error +fn1([1]); // Error +fn1([1, 'abc']); // [number, string] +fn1([1, 'abc', true]); // [string, boolean] +fn2([]); // Error +fn2([1]); // Error +fn2([1, 'abc']); // [number, string] +fn2([1, 'abc', true]); // [number, boolean] +var a1 = foo('blah1', 1); +var b1 = foo('blah1', 'blah2', 1); +var c1 = foo(1); // Error +var d1 = foo(1, 2); // Error +var e1 = foo('blah1', 'blah2', 1, 2, 3); // Error + + +//// [variadicTuples2.d.ts] +declare type V00 = [number, ...string[]]; +declare type V01 = [...string[], number]; +declare type V03 = [number, ...string[], number]; +declare type V10 = [number, ...string[], ...boolean[]]; +declare type V11 = [number, ...string[], boolean?]; +declare type V12 = [number, string?, boolean]; +declare type Tup3 = [...T, ...U, ...V]; +declare type V20 = Tup3<[number], string[], [number]>; +declare type V21 = Tup3<[number], [string?], [boolean]>; +declare type V22 = Tup3<[number], string[], boolean[]>; +declare type V23 = Tup3<[number], string[], [boolean?]>; +declare type V24 = Tup3<[number], [boolean?], string[]>; +declare type V25 = Tup3; +declare type V26 = Tup3; +declare type V27 = Tup3<[number?], [string], [boolean?]>; +declare type V30 = Tup3; +declare type V31 = Tup3; +declare type V32 = Tup3; +declare type V40 = Tup3; +declare type V41 = Tup3<[string?], A, number[]>; +declare type V42 = Tup3<[string?], number[], A>; +declare type V50 = Tup3; +declare type V51 = Tup3; +declare type V52 = Tup3; +declare let tt1: [...string[], number]; +declare function ft1(...args: [...strs: string[], num: number]): void; +declare let tt2: [number, ...string[], number]; +declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; +declare function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]): void; +declare function pipe(...args: [...T, (...values: T) => void]): void; +declare const sa: string[]; +declare function fn1(t: [...unknown[], T, U]): [T, U]; +declare function fn2(t: [T, ...unknown[], U]): [T, U]; +declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; +declare const a1: ["blah1", number]; +declare const b1: ["blah1", "blah2", number]; +declare const c1: [string, ...string[], number]; +declare const d1: [string, ...string[], number]; +declare const e1: [string, ...string[], number]; diff --git a/tests/baselines/reference/variadicTuples2.symbols b/tests/baselines/reference/variadicTuples2.symbols new file mode 100644 index 0000000000000..82f2ccb86a89a --- /dev/null +++ b/tests/baselines/reference/variadicTuples2.symbols @@ -0,0 +1,404 @@ +=== tests/cases/conformance/types/tuple/variadicTuples2.ts === +// Declarations + +type V00 = [number, ...string[]]; +>V00 : Symbol(V00, Decl(variadicTuples2.ts, 0, 0)) + +type V01 = [...string[], number]; +>V01 : Symbol(V01, Decl(variadicTuples2.ts, 2, 33)) + +type V03 = [number, ...string[], number]; +>V03 : Symbol(V03, Decl(variadicTuples2.ts, 3, 33)) + +type V10 = [number, ...string[], ...boolean[]]; // Error +>V10 : Symbol(V10, Decl(variadicTuples2.ts, 4, 41)) + +type V11 = [number, ...string[], boolean?]; // Error +>V11 : Symbol(V11, Decl(variadicTuples2.ts, 6, 47)) + +type V12 = [number, string?, boolean]; // Error +>V12 : Symbol(V12, Decl(variadicTuples2.ts, 7, 43)) + +// Normalization + +type Tup3 = [...T, ...U, ...V]; +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>T : Symbol(T, Decl(variadicTuples2.ts, 12, 10)) +>U : Symbol(U, Decl(variadicTuples2.ts, 12, 30)) +>V : Symbol(V, Decl(variadicTuples2.ts, 12, 51)) +>T : Symbol(T, Decl(variadicTuples2.ts, 12, 10)) +>U : Symbol(U, Decl(variadicTuples2.ts, 12, 30)) +>V : Symbol(V, Decl(variadicTuples2.ts, 12, 51)) + +type V20 = Tup3<[number], string[], [number]>; // [number, ...string[], number] +>V20 : Symbol(V20, Decl(variadicTuples2.ts, 12, 94)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V21 = Tup3<[number], [string?], [boolean]>; // [number, string | undefined, boolean] +>V21 : Symbol(V21, Decl(variadicTuples2.ts, 14, 46)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V22 = Tup3<[number], string[], boolean[]>; // [number, (string | boolean)[]] +>V22 : Symbol(V22, Decl(variadicTuples2.ts, 15, 48)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V23 = Tup3<[number], string[], [boolean?]>; // [number, (string | boolean | undefined)[]] +>V23 : Symbol(V23, Decl(variadicTuples2.ts, 16, 47)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V24 = Tup3<[number], [boolean?], string[]>; // [number, boolean?, ...string[]] +>V24 : Symbol(V24, Decl(variadicTuples2.ts, 17, 48)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V25 = Tup3; // (string | number | boolean)[] +>V25 : Symbol(V25, Decl(variadicTuples2.ts, 18, 48)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V26 = Tup3; // [...(string | number)[], boolean] +>V26 : Symbol(V26, Decl(variadicTuples2.ts, 19, 47)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V27 = Tup3<[number?], [string], [boolean?]>; // [number | undefined, string, boolean?] +>V27 : Symbol(V27, Decl(variadicTuples2.ts, 20, 47)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) + +type V30 = Tup3; // [...A, ...(string | number)[]] +>V30 : Symbol(V30, Decl(variadicTuples2.ts, 21, 49)) +>A : Symbol(A, Decl(variadicTuples2.ts, 23, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 23, 9)) + +type V31 = Tup3; // (string | number | A[number])[] +>V31 : Symbol(V31, Decl(variadicTuples2.ts, 23, 60)) +>A : Symbol(A, Decl(variadicTuples2.ts, 24, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 24, 9)) + +type V32 = Tup3; // [...(string | number)[], ...A] +>V32 : Symbol(V32, Decl(variadicTuples2.ts, 24, 60)) +>A : Symbol(A, Decl(variadicTuples2.ts, 25, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 25, 9)) + +type V40 = Tup3; // [...A, string?, ...number[]] +>V40 : Symbol(V40, Decl(variadicTuples2.ts, 25, 60)) +>A : Symbol(A, Decl(variadicTuples2.ts, 27, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 27, 9)) + +type V41 = Tup3<[string?], A, number[]>; // [string?, ...A, ...number[]] +>V41 : Symbol(V41, Decl(variadicTuples2.ts, 27, 61)) +>A : Symbol(A, Decl(variadicTuples2.ts, 28, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 28, 9)) + +type V42 = Tup3<[string?], number[], A>; // [string?, ...number[], ...A] +>V42 : Symbol(V42, Decl(variadicTuples2.ts, 28, 61)) +>A : Symbol(A, Decl(variadicTuples2.ts, 29, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 29, 9)) + +type V50 = Tup3; // [...A, ...(string | number | undefined)[]] +>V50 : Symbol(V50, Decl(variadicTuples2.ts, 29, 61)) +>A : Symbol(A, Decl(variadicTuples2.ts, 31, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 31, 9)) + +type V51 = Tup3; // (string | number | A[number] | undefined)[] +>V51 : Symbol(V51, Decl(variadicTuples2.ts, 31, 61)) +>A : Symbol(A, Decl(variadicTuples2.ts, 32, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 32, 9)) + +type V52 = Tup3; // [...(string | number | undefined)[], ...A] +>V52 : Symbol(V52, Decl(variadicTuples2.ts, 32, 61)) +>A : Symbol(A, Decl(variadicTuples2.ts, 33, 9)) +>Tup3 : Symbol(Tup3, Decl(variadicTuples2.ts, 8, 38)) +>A : Symbol(A, Decl(variadicTuples2.ts, 33, 9)) + +// Assignability + +declare let tt1: [...string[], number]; +>tt1 : Symbol(tt1, Decl(variadicTuples2.ts, 37, 11)) + +tt1 = [5]; +>tt1 : Symbol(tt1, Decl(variadicTuples2.ts, 37, 11)) + +tt1 = ['abc', 5]; +>tt1 : Symbol(tt1, Decl(variadicTuples2.ts, 37, 11)) + +tt1 = ['abc', 'def', 5]; +>tt1 : Symbol(tt1, Decl(variadicTuples2.ts, 37, 11)) + +tt1 = ['abc', 'def', 5, 6]; // Error +>tt1 : Symbol(tt1, Decl(variadicTuples2.ts, 37, 11)) + +declare function ft1(...args: [...strs: string[], num: number]): void; +>ft1 : Symbol(ft1, Decl(variadicTuples2.ts, 41, 27)) +>args : Symbol(args, Decl(variadicTuples2.ts, 43, 21)) + +ft1(5); +>ft1 : Symbol(ft1, Decl(variadicTuples2.ts, 41, 27)) + +ft1('abc', 5); +>ft1 : Symbol(ft1, Decl(variadicTuples2.ts, 41, 27)) + +ft1('abc', 'def', 5); +>ft1 : Symbol(ft1, Decl(variadicTuples2.ts, 41, 27)) + +ft1('abc', 'def', 5, 6); // Error +>ft1 : Symbol(ft1, Decl(variadicTuples2.ts, 41, 27)) + +declare let tt2: [number, ...string[], number]; +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0]; // Error +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0, 1]; +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0, 1, 2]; // Error +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0, 'abc', 1]; +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0, 'abc', 'def', 1]; +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0, 'abc', 1, 'def']; // Error +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [true, 'abc', 'def', 1]; // Error +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +tt2 = [0, 'abc', 'def', true]; // Error +>tt2 : Symbol(tt2, Decl(variadicTuples2.ts, 49, 11)) + +declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) +>n1 : Symbol(n1, Decl(variadicTuples2.ts, 59, 21)) +>rest : Symbol(rest, Decl(variadicTuples2.ts, 59, 32)) + +ft2(0); // Error +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(0, 1); +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(0, 1, 2); // Error +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(0, 'abc', 1); +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(0, 'abc', 'def', 1); +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(0, 'abc', 1, 'def'); // Error +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(true, 'abc', 'def', 1); // Error +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +ft2(0, 'abc', 'def', true); // Error +>ft2 : Symbol(ft2, Decl(variadicTuples2.ts, 57, 30)) + +function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]) { +>ft3 : Symbol(ft3, Decl(variadicTuples2.ts, 67, 27)) +>T : Symbol(T, Decl(variadicTuples2.ts, 69, 13)) +>x : Symbol(x, Decl(variadicTuples2.ts, 69, 34)) +>T : Symbol(T, Decl(variadicTuples2.ts, 69, 13)) +>y : Symbol(y, Decl(variadicTuples2.ts, 69, 52)) +>z : Symbol(z, Decl(variadicTuples2.ts, 69, 73)) + + x = y; // Error +>x : Symbol(x, Decl(variadicTuples2.ts, 69, 34)) +>y : Symbol(y, Decl(variadicTuples2.ts, 69, 52)) + + x = z; // Error +>x : Symbol(x, Decl(variadicTuples2.ts, 69, 34)) +>z : Symbol(z, Decl(variadicTuples2.ts, 69, 73)) + + y = x; // Error +>y : Symbol(y, Decl(variadicTuples2.ts, 69, 52)) +>x : Symbol(x, Decl(variadicTuples2.ts, 69, 34)) + + z = x; // Error +>z : Symbol(z, Decl(variadicTuples2.ts, 69, 73)) +>x : Symbol(x, Decl(variadicTuples2.ts, 69, 34)) +} + +// Inference + +function pipe(...args: [...T, (...values: T) => void]) { +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) +>args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) +>values : Symbol(values, Decl(variadicTuples2.ts, 78, 61)) +>T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) + + const callback = args[args.length - 1] as (...values: T) => void; +>callback : Symbol(callback, Decl(variadicTuples2.ts, 79, 9)) +>args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>args.length : Symbol(length) +>args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>length : Symbol(length) +>values : Symbol(values, Decl(variadicTuples2.ts, 79, 47)) +>T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) + + const values = args.slice(0, -1) as unknown as T; +>values : Symbol(values, Decl(variadicTuples2.ts, 80, 9)) +>args.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) + + callback(...values); +>callback : Symbol(callback, Decl(variadicTuples2.ts, 79, 9)) +>values : Symbol(values, Decl(variadicTuples2.ts, 80, 9)) +} + +pipe("foo", 123, true, (a, b, c) => { +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>a : Symbol(a, Decl(variadicTuples2.ts, 84, 24)) +>b : Symbol(b, Decl(variadicTuples2.ts, 84, 26)) +>c : Symbol(c, Decl(variadicTuples2.ts, 84, 29)) + + a; // string +>a : Symbol(a, Decl(variadicTuples2.ts, 84, 24)) + + b; // number +>b : Symbol(b, Decl(variadicTuples2.ts, 84, 26)) + + c; // boolean +>c : Symbol(c, Decl(variadicTuples2.ts, 84, 29)) + +}) + +pipe("foo", 123, true, (...x) => { +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>x : Symbol(x, Decl(variadicTuples2.ts, 90, 24)) + + x; // [string, number, boolean] +>x : Symbol(x, Decl(variadicTuples2.ts, 90, 24)) + +}); + +declare const sa: string[]; +>sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) + +pipe(...sa, (...x) => { +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) +>x : Symbol(x, Decl(variadicTuples2.ts, 96, 13)) + + x; // string[] +>x : Symbol(x, Decl(variadicTuples2.ts, 96, 13)) + +}); + +pipe(1, ...sa, 2, (...x) => { +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) + + x; // [number, ...string[], number] +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) + + let qq = x[x.length - 1]; +>qq : Symbol(qq, Decl(variadicTuples2.ts, 102, 7)) +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>x.length : Symbol(length) +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>length : Symbol(length) + + let ww = x[0] +>ww : Symbol(ww, Decl(variadicTuples2.ts, 103, 7)) +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>0 : Symbol(0) + +}); + +pipe(1, 2, 3, 4); // Error +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) + +pipe(...sa); // Error +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) + +declare function fn1(t: [...unknown[], T, U]): [T, U]; +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) +>T : Symbol(T, Decl(variadicTuples2.ts, 109, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 109, 23)) +>t : Symbol(t, Decl(variadicTuples2.ts, 109, 27)) +>T : Symbol(T, Decl(variadicTuples2.ts, 109, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 109, 23)) +>T : Symbol(T, Decl(variadicTuples2.ts, 109, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 109, 23)) + +fn1([]); // Error +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) + +fn1([1]); // Error +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) + +fn1([1, 'abc']); // [number, string] +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) + +fn1([1, 'abc', true]); // [string, boolean] +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) + +declare function fn2(t: [T, ...unknown[], U]): [T, U]; +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) +>T : Symbol(T, Decl(variadicTuples2.ts, 115, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 115, 23)) +>t : Symbol(t, Decl(variadicTuples2.ts, 115, 27)) +>T : Symbol(T, Decl(variadicTuples2.ts, 115, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 115, 23)) +>T : Symbol(T, Decl(variadicTuples2.ts, 115, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 115, 23)) + +fn2([]); // Error +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) + +fn2([1]); // Error +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) + +fn2([1, 'abc']); // [number, string] +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) + +fn2([1, 'abc', true]); // [number, boolean] +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) + +// Repro from #39595 + +declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; +>foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) +>S : Symbol(S, Decl(variadicTuples2.ts, 123, 21)) +>stringsAndNumber : Symbol(stringsAndNumber, Decl(variadicTuples2.ts, 123, 63)) +>S : Symbol(S, Decl(variadicTuples2.ts, 123, 21)) +>S : Symbol(S, Decl(variadicTuples2.ts, 123, 21)) + +const a1 = foo('blah1', 1); +>a1 : Symbol(a1, Decl(variadicTuples2.ts, 125, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) + +const b1 = foo('blah1', 'blah2', 1); +>b1 : Symbol(b1, Decl(variadicTuples2.ts, 126, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) + +const c1 = foo(1); // Error +>c1 : Symbol(c1, Decl(variadicTuples2.ts, 127, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) + +const d1 = foo(1, 2); // Error +>d1 : Symbol(d1, Decl(variadicTuples2.ts, 128, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) + +const e1 = foo('blah1', 'blah2', 1, 2, 3); // Error +>e1 : Symbol(e1, Decl(variadicTuples2.ts, 129, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) + diff --git a/tests/baselines/reference/variadicTuples2.types b/tests/baselines/reference/variadicTuples2.types new file mode 100644 index 0000000000000..b60c45bc727f6 --- /dev/null +++ b/tests/baselines/reference/variadicTuples2.types @@ -0,0 +1,538 @@ +=== tests/cases/conformance/types/tuple/variadicTuples2.ts === +// Declarations + +type V00 = [number, ...string[]]; +>V00 : V00 + +type V01 = [...string[], number]; +>V01 : V01 + +type V03 = [number, ...string[], number]; +>V03 : V03 + +type V10 = [number, ...string[], ...boolean[]]; // Error +>V10 : V10 + +type V11 = [number, ...string[], boolean?]; // Error +>V11 : V11 + +type V12 = [number, string?, boolean]; // Error +>V12 : V12 + +// Normalization + +type Tup3 = [...T, ...U, ...V]; +>Tup3 : [...T, ...U, ...V] + +type V20 = Tup3<[number], string[], [number]>; // [number, ...string[], number] +>V20 : [number, ...string[], number] + +type V21 = Tup3<[number], [string?], [boolean]>; // [number, string | undefined, boolean] +>V21 : [number, string | undefined, boolean] + +type V22 = Tup3<[number], string[], boolean[]>; // [number, (string | boolean)[]] +>V22 : [number, ...(string | boolean)[]] + +type V23 = Tup3<[number], string[], [boolean?]>; // [number, (string | boolean | undefined)[]] +>V23 : [number, ...(string | boolean | undefined)[]] + +type V24 = Tup3<[number], [boolean?], string[]>; // [number, boolean?, ...string[]] +>V24 : [number, (boolean | undefined)?, ...string[]] + +type V25 = Tup3; // (string | number | boolean)[] +>V25 : (string | number | boolean)[] + +type V26 = Tup3; // [...(string | number)[], boolean] +>V26 : [...(string | number)[], boolean] + +type V27 = Tup3<[number?], [string], [boolean?]>; // [number | undefined, string, boolean?] +>V27 : [number | undefined, string, (boolean | undefined)?] + +type V30 = Tup3; // [...A, ...(string | number)[]] +>V30 : [...A, ...(string | number)[]] + +type V31 = Tup3; // (string | number | A[number])[] +>V31 : (string | number | A[number])[] + +type V32 = Tup3; // [...(string | number)[], ...A] +>V32 : [...(string | number)[], ...A] + +type V40 = Tup3; // [...A, string?, ...number[]] +>V40 : [...A, (string | undefined)?, ...number[]] + +type V41 = Tup3<[string?], A, number[]>; // [string?, ...A, ...number[]] +>V41 : [(string | undefined)?, ...A, ...number[]] + +type V42 = Tup3<[string?], number[], A>; // [string?, ...number[], ...A] +>V42 : [(string | undefined)?, ...number[], ...A] + +type V50 = Tup3; // [...A, ...(string | number | undefined)[]] +>V50 : [...A, ...(string | number | undefined)[]] + +type V51 = Tup3; // (string | number | A[number] | undefined)[] +>V51 : (string | number | A[number] | undefined)[] + +type V52 = Tup3; // [...(string | number | undefined)[], ...A] +>V52 : [...(string | number | undefined)[], ...A] + +// Assignability + +declare let tt1: [...string[], number]; +>tt1 : [...string[], number] + +tt1 = [5]; +>tt1 = [5] : [number] +>tt1 : [...string[], number] +>[5] : [number] +>5 : 5 + +tt1 = ['abc', 5]; +>tt1 = ['abc', 5] : [string, number] +>tt1 : [...string[], number] +>['abc', 5] : [string, number] +>'abc' : "abc" +>5 : 5 + +tt1 = ['abc', 'def', 5]; +>tt1 = ['abc', 'def', 5] : [string, string, number] +>tt1 : [...string[], number] +>['abc', 'def', 5] : [string, string, number] +>'abc' : "abc" +>'def' : "def" +>5 : 5 + +tt1 = ['abc', 'def', 5, 6]; // Error +>tt1 = ['abc', 'def', 5, 6] : [string, string, number, number] +>tt1 : [...string[], number] +>['abc', 'def', 5, 6] : [string, string, number, number] +>'abc' : "abc" +>'def' : "def" +>5 : 5 +>6 : 6 + +declare function ft1(...args: [...strs: string[], num: number]): void; +>ft1 : (...args: [...strs: string[], num: number]) => void +>args : [...strs: string[], num: number] + +ft1(5); +>ft1(5) : void +>ft1 : (...args: [...strs: string[], num: number]) => void +>5 : 5 + +ft1('abc', 5); +>ft1('abc', 5) : void +>ft1 : (...args: [...strs: string[], num: number]) => void +>'abc' : "abc" +>5 : 5 + +ft1('abc', 'def', 5); +>ft1('abc', 'def', 5) : void +>ft1 : (...args: [...strs: string[], num: number]) => void +>'abc' : "abc" +>'def' : "def" +>5 : 5 + +ft1('abc', 'def', 5, 6); // Error +>ft1('abc', 'def', 5, 6) : void +>ft1 : (...args: [...strs: string[], num: number]) => void +>'abc' : "abc" +>'def' : "def" +>5 : 5 +>6 : 6 + +declare let tt2: [number, ...string[], number]; +>tt2 : [number, ...string[], number] + +tt2 = [0]; // Error +>tt2 = [0] : [number] +>tt2 : [number, ...string[], number] +>[0] : [number] +>0 : 0 + +tt2 = [0, 1]; +>tt2 = [0, 1] : [number, number] +>tt2 : [number, ...string[], number] +>[0, 1] : [number, number] +>0 : 0 +>1 : 1 + +tt2 = [0, 1, 2]; // Error +>tt2 = [0, 1, 2] : [number, number, number] +>tt2 : [number, ...string[], number] +>[0, 1, 2] : [number, number, number] +>0 : 0 +>1 : 1 +>2 : 2 + +tt2 = [0, 'abc', 1]; +>tt2 = [0, 'abc', 1] : [number, string, number] +>tt2 : [number, ...string[], number] +>[0, 'abc', 1] : [number, string, number] +>0 : 0 +>'abc' : "abc" +>1 : 1 + +tt2 = [0, 'abc', 'def', 1]; +>tt2 = [0, 'abc', 'def', 1] : [number, string, string, number] +>tt2 : [number, ...string[], number] +>[0, 'abc', 'def', 1] : [number, string, string, number] +>0 : 0 +>'abc' : "abc" +>'def' : "def" +>1 : 1 + +tt2 = [0, 'abc', 1, 'def']; // Error +>tt2 = [0, 'abc', 1, 'def'] : [number, string, number, string] +>tt2 : [number, ...string[], number] +>[0, 'abc', 1, 'def'] : [number, string, number, string] +>0 : 0 +>'abc' : "abc" +>1 : 1 +>'def' : "def" + +tt2 = [true, 'abc', 'def', 1]; // Error +>tt2 = [true, 'abc', 'def', 1] : [boolean, string, string, number] +>tt2 : [number, ...string[], number] +>[true, 'abc', 'def', 1] : [boolean, string, string, number] +>true : true +>'abc' : "abc" +>'def' : "def" +>1 : 1 + +tt2 = [0, 'abc', 'def', true]; // Error +>tt2 = [0, 'abc', 'def', true] : [number, string, string, boolean] +>tt2 : [number, ...string[], number] +>[0, 'abc', 'def', true] : [number, string, string, boolean] +>0 : 0 +>'abc' : "abc" +>'def' : "def" +>true : true + +declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>n1 : number +>rest : [...strs: string[], n2: number] + +ft2(0); // Error +>ft2(0) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 + +ft2(0, 1); +>ft2(0, 1) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 +>1 : 1 + +ft2(0, 1, 2); // Error +>ft2(0, 1, 2) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 +>1 : 1 +>2 : 2 + +ft2(0, 'abc', 1); +>ft2(0, 'abc', 1) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 +>'abc' : "abc" +>1 : 1 + +ft2(0, 'abc', 'def', 1); +>ft2(0, 'abc', 'def', 1) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 +>'abc' : "abc" +>'def' : "def" +>1 : 1 + +ft2(0, 'abc', 1, 'def'); // Error +>ft2(0, 'abc', 1, 'def') : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 +>'abc' : "abc" +>1 : 1 +>'def' : "def" + +ft2(true, 'abc', 'def', 1); // Error +>ft2(true, 'abc', 'def', 1) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>true : true +>'abc' : "abc" +>'def' : "def" +>1 : 1 + +ft2(0, 'abc', 'def', true); // Error +>ft2(0, 'abc', 'def', true) : void +>ft2 : (n1: number, ...rest: [...strs: string[], n2: number]) => void +>0 : 0 +>'abc' : "abc" +>'def' : "def" +>true : true + +function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]) { +>ft3 : (x: [number, ...T], y: [number, number], z: [number, ...number[]]) => void +>x : [number, ...T] +>y : [number, number] +>z : [number, ...number[]] + + x = y; // Error +>x = y : [number, number] +>x : [number, ...T] +>y : [number, number] + + x = z; // Error +>x = z : [number, ...number[]] +>x : [number, ...T] +>z : [number, ...number[]] + + y = x; // Error +>y = x : [number, ...T] +>y : [number, number] +>x : [number, ...T] + + z = x; // Error +>z = x : [number, ...T] +>z : [number, ...number[]] +>x : [number, ...T] +} + +// Inference + +function pipe(...args: [...T, (...values: T) => void]) { +>pipe : (...args: [...T, (...values: T) => void]) => void +>args : [...T, (...values: T) => void] +>values : T + + const callback = args[args.length - 1] as (...values: T) => void; +>callback : (...values: T) => void +>args[args.length - 1] as (...values: T) => void : (...values: T) => void +>args[args.length - 1] : [...T, (...values: T) => void][number] +>args : [...T, (...values: T) => void] +>args.length - 1 : number +>args.length : number +>args : [...T, (...values: T) => void] +>length : number +>1 : 1 +>values : T + + const values = args.slice(0, -1) as unknown as T; +>values : T +>args.slice(0, -1) as unknown as T : T +>args.slice(0, -1) as unknown : unknown +>args.slice(0, -1) : (((...values: T) => void) | T[number])[] +>args.slice : (start?: number | undefined, end?: number | undefined) => (((...values: T) => void) | T[number])[] +>args : [...T, (...values: T) => void] +>slice : (start?: number | undefined, end?: number | undefined) => (((...values: T) => void) | T[number])[] +>0 : 0 +>-1 : -1 +>1 : 1 + + callback(...values); +>callback(...values) : void +>callback : (...values: T) => void +>...values : unknown +>values : T +} + +pipe("foo", 123, true, (a, b, c) => { +>pipe("foo", 123, true, (a, b, c) => { a; // string b; // number c; // boolean}) : void +>pipe : (...args: [...T, (...values: T) => void]) => void +>"foo" : "foo" +>123 : 123 +>true : true +>(a, b, c) => { a; // string b; // number c; // boolean} : (a: string, b: number, c: boolean) => void +>a : string +>b : number +>c : boolean + + a; // string +>a : string + + b; // number +>b : number + + c; // boolean +>c : boolean + +}) + +pipe("foo", 123, true, (...x) => { +>pipe("foo", 123, true, (...x) => { x; // [string, number, boolean]}) : void +>pipe : (...args: [...T, (...values: T) => void]) => void +>"foo" : "foo" +>123 : 123 +>true : true +>(...x) => { x; // [string, number, boolean]} : (x_0: string, x_1: number, x_2: boolean) => void +>x : [string, number, boolean] + + x; // [string, number, boolean] +>x : [string, number, boolean] + +}); + +declare const sa: string[]; +>sa : string[] + +pipe(...sa, (...x) => { +>pipe(...sa, (...x) => { x; // string[]}) : void +>pipe : (...args: [...T, (...values: T) => void]) => void +>...sa : string +>sa : string[] +>(...x) => { x; // string[]} : (...x: string[]) => void +>x : string[] + + x; // string[] +>x : string[] + +}); + +pipe(1, ...sa, 2, (...x) => { +>pipe(1, ...sa, 2, (...x) => { x; // [number, ...string[], number] let qq = x[x.length - 1]; let ww = x[0]}) : void +>pipe : (...args: [...T, (...values: T) => void]) => void +>1 : 1 +>...sa : string +>sa : string[] +>2 : 2 +>(...x) => { x; // [number, ...string[], number] let qq = x[x.length - 1]; let ww = x[0]} : (...x: [number, ...string[], number]) => void +>x : [number, ...string[], number] + + x; // [number, ...string[], number] +>x : [number, ...string[], number] + + let qq = x[x.length - 1]; +>qq : string | number +>x[x.length - 1] : string | number +>x : [number, ...string[], number] +>x.length - 1 : number +>x.length : number +>x : [number, ...string[], number] +>length : number +>1 : 1 + + let ww = x[0] +>ww : number +>x[0] : number +>x : [number, ...string[], number] +>0 : 0 + +}); + +pipe(1, 2, 3, 4); // Error +>pipe(1, 2, 3, 4) : void +>pipe : (...args: [...T, (...values: T) => void]) => void +>1 : 1 +>2 : 2 +>3 : 3 +>4 : 4 + +pipe(...sa); // Error +>pipe(...sa) : void +>pipe : (...args: [...T, (...values: T) => void]) => void +>...sa : string +>sa : string[] + +declare function fn1(t: [...unknown[], T, U]): [T, U]; +>fn1 : (t: [...unknown[], T, U]) => [T, U] +>t : [...unknown[], T, U] + +fn1([]); // Error +>fn1([]) : [unknown, unknown] +>fn1 : (t: [...unknown[], T, U]) => [T, U] +>[] : [] + +fn1([1]); // Error +>fn1([1]) : [unknown, unknown] +>fn1 : (t: [...unknown[], T, U]) => [T, U] +>[1] : [number] +>1 : 1 + +fn1([1, 'abc']); // [number, string] +>fn1([1, 'abc']) : [number, string] +>fn1 : (t: [...unknown[], T, U]) => [T, U] +>[1, 'abc'] : [number, string] +>1 : 1 +>'abc' : "abc" + +fn1([1, 'abc', true]); // [string, boolean] +>fn1([1, 'abc', true]) : [string, boolean] +>fn1 : (t: [...unknown[], T, U]) => [T, U] +>[1, 'abc', true] : [number, string, boolean] +>1 : 1 +>'abc' : "abc" +>true : true + +declare function fn2(t: [T, ...unknown[], U]): [T, U]; +>fn2 : (t: [T, ...unknown[], U]) => [T, U] +>t : [T, ...unknown[], U] + +fn2([]); // Error +>fn2([]) : [unknown, unknown] +>fn2 : (t: [T, ...unknown[], U]) => [T, U] +>[] : [] + +fn2([1]); // Error +>fn2([1]) : [unknown, unknown] +>fn2 : (t: [T, ...unknown[], U]) => [T, U] +>[1] : [number] +>1 : 1 + +fn2([1, 'abc']); // [number, string] +>fn2([1, 'abc']) : [number, string] +>fn2 : (t: [T, ...unknown[], U]) => [T, U] +>[1, 'abc'] : [number, string] +>1 : 1 +>'abc' : "abc" + +fn2([1, 'abc', true]); // [number, boolean] +>fn2([1, 'abc', true]) : [number, boolean] +>fn2 : (t: [T, ...unknown[], U]) => [T, U] +>[1, 'abc', true] : [number, string, boolean] +>1 : 1 +>'abc' : "abc" +>true : true + +// Repro from #39595 + +declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; +>foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] +>stringsAndNumber : readonly [...S, number] + +const a1 = foo('blah1', 1); +>a1 : ["blah1", number] +>foo('blah1', 1) : ["blah1", number] +>foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] +>'blah1' : "blah1" +>1 : 1 + +const b1 = foo('blah1', 'blah2', 1); +>b1 : ["blah1", "blah2", number] +>foo('blah1', 'blah2', 1) : ["blah1", "blah2", number] +>foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] +>'blah1' : "blah1" +>'blah2' : "blah2" +>1 : 1 + +const c1 = foo(1); // Error +>c1 : [string, ...string[], number] +>foo(1) : [string, ...string[], number] +>foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] +>1 : 1 + +const d1 = foo(1, 2); // Error +>d1 : [string, ...string[], number] +>foo(1, 2) : [string, ...string[], number] +>foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] +>1 : 1 +>2 : 2 + +const e1 = foo('blah1', 'blah2', 1, 2, 3); // Error +>e1 : [string, ...string[], number] +>foo('blah1', 'blah2', 1, 2, 3) : [string, ...string[], number] +>foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] +>'blah1' : "blah1" +>'blah2' : "blah2" +>1 : 1 +>2 : 2 +>3 : 3 + diff --git a/tests/cases/conformance/types/tuple/variadicTuples2.ts b/tests/cases/conformance/types/tuple/variadicTuples2.ts new file mode 100644 index 0000000000000..aa34bd4630c0c --- /dev/null +++ b/tests/cases/conformance/types/tuple/variadicTuples2.ts @@ -0,0 +1,133 @@ +// @strict: true +// @declaration: true + +// Declarations + +type V00 = [number, ...string[]]; +type V01 = [...string[], number]; +type V03 = [number, ...string[], number]; + +type V10 = [number, ...string[], ...boolean[]]; // Error +type V11 = [number, ...string[], boolean?]; // Error +type V12 = [number, string?, boolean]; // Error + +// Normalization + +type Tup3 = [...T, ...U, ...V]; + +type V20 = Tup3<[number], string[], [number]>; // [number, ...string[], number] +type V21 = Tup3<[number], [string?], [boolean]>; // [number, string | undefined, boolean] +type V22 = Tup3<[number], string[], boolean[]>; // [number, (string | boolean)[]] +type V23 = Tup3<[number], string[], [boolean?]>; // [number, (string | boolean | undefined)[]] +type V24 = Tup3<[number], [boolean?], string[]>; // [number, boolean?, ...string[]] +type V25 = Tup3; // (string | number | boolean)[] +type V26 = Tup3; // [...(string | number)[], boolean] +type V27 = Tup3<[number?], [string], [boolean?]>; // [number | undefined, string, boolean?] + +type V30 = Tup3; // [...A, ...(string | number)[]] +type V31 = Tup3; // (string | number | A[number])[] +type V32 = Tup3; // [...(string | number)[], ...A] + +type V40 = Tup3; // [...A, string?, ...number[]] +type V41 = Tup3<[string?], A, number[]>; // [string?, ...A, ...number[]] +type V42 = Tup3<[string?], number[], A>; // [string?, ...number[], ...A] + +type V50 = Tup3; // [...A, ...(string | number | undefined)[]] +type V51 = Tup3; // (string | number | A[number] | undefined)[] +type V52 = Tup3; // [...(string | number | undefined)[], ...A] + +// Assignability + +declare let tt1: [...string[], number]; +tt1 = [5]; +tt1 = ['abc', 5]; +tt1 = ['abc', 'def', 5]; +tt1 = ['abc', 'def', 5, 6]; // Error + +declare function ft1(...args: [...strs: string[], num: number]): void; +ft1(5); +ft1('abc', 5); +ft1('abc', 'def', 5); +ft1('abc', 'def', 5, 6); // Error + +declare let tt2: [number, ...string[], number]; +tt2 = [0]; // Error +tt2 = [0, 1]; +tt2 = [0, 1, 2]; // Error +tt2 = [0, 'abc', 1]; +tt2 = [0, 'abc', 'def', 1]; +tt2 = [0, 'abc', 1, 'def']; // Error +tt2 = [true, 'abc', 'def', 1]; // Error +tt2 = [0, 'abc', 'def', true]; // Error + +declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; +ft2(0); // Error +ft2(0, 1); +ft2(0, 1, 2); // Error +ft2(0, 'abc', 1); +ft2(0, 'abc', 'def', 1); +ft2(0, 'abc', 1, 'def'); // Error +ft2(true, 'abc', 'def', 1); // Error +ft2(0, 'abc', 'def', true); // Error + +function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]) { + x = y; // Error + x = z; // Error + y = x; // Error + z = x; // Error +} + +// Inference + +function pipe(...args: [...T, (...values: T) => void]) { + const callback = args[args.length - 1] as (...values: T) => void; + const values = args.slice(0, -1) as unknown as T; + callback(...values); +} + +pipe("foo", 123, true, (a, b, c) => { + a; // string + b; // number + c; // boolean +}) + +pipe("foo", 123, true, (...x) => { + x; // [string, number, boolean] +}); + +declare const sa: string[]; + +pipe(...sa, (...x) => { + x; // string[] +}); + +pipe(1, ...sa, 2, (...x) => { + x; // [number, ...string[], number] + let qq = x[x.length - 1]; + let ww = x[0] +}); + +pipe(1, 2, 3, 4); // Error +pipe(...sa); // Error + +declare function fn1(t: [...unknown[], T, U]): [T, U]; +fn1([]); // Error +fn1([1]); // Error +fn1([1, 'abc']); // [number, string] +fn1([1, 'abc', true]); // [string, boolean] + +declare function fn2(t: [T, ...unknown[], U]): [T, U]; +fn2([]); // Error +fn2([1]); // Error +fn2([1, 'abc']); // [number, string] +fn2([1, 'abc', true]); // [number, boolean] + +// Repro from #39595 + +declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; + +const a1 = foo('blah1', 1); +const b1 = foo('blah1', 'blah2', 1); +const c1 = foo(1); // Error +const d1 = foo(1, 2); // Error +const e1 = foo('blah1', 'blah2', 1, 2, 3); // Error From 77722bb64c311acbc07d83192e85a0f9758bbb08 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Nov 2020 17:08:06 -0800 Subject: [PATCH 7/7] Fix lint errors --- src/compiler/checker.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9e91a31b57c5c..988e78a830340 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18173,7 +18173,6 @@ namespace ts { return Ternary.False; } result &= related; - } return result; } @@ -31928,8 +31927,7 @@ namespace ts { let seenOptionalElement = false; let seenRestElement = false; const hasNamedElement = some(elementTypes, isNamedTupleMember); - for (let i = 0; i < elementTypes.length; i++) { - const e = elementTypes[i]; + for (const e of elementTypes) { if (e.kind !== SyntaxKind.NamedTupleMember && hasNamedElement) { grammarErrorOnNode(e, Diagnostics.Tuple_members_must_all_have_names_or_all_not_have_names); break;