From b7816eac3c6b7e0957c8b243b4c96218f0678585 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 19 Mar 2023 14:59:25 -0400 Subject: [PATCH 01/16] Allowed tuples to have both named and anonymous members --- src/compiler/checker.ts | 62 ++++++++++--------- src/compiler/diagnosticMessages.json | 4 -- src/compiler/types.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../namedTupleMembersErrors.errors.txt | 32 +++------- .../reference/namedTupleMembersErrors.js | 12 ++-- .../reference/namedTupleMembersErrors.symbols | 12 ++-- .../reference/namedTupleMembersErrors.types | 20 +++--- .../reference/partiallyNamedTuples.js | 44 +++++++++++++ .../reference/partiallyNamedTuples.symbols | 39 ++++++++++++ .../reference/partiallyNamedTuples.types | 30 +++++++++ .../tuple/named/namedTupleMembersErrors.ts | 12 ++-- .../types/tuple/named/partiallyNamedTuples.ts | 10 +++ 14 files changed, 195 insertions(+), 88 deletions(-) create mode 100644 tests/baselines/reference/partiallyNamedTuples.js create mode 100644 tests/baselines/reference/partiallyNamedTuples.symbols create mode 100644 tests/baselines/reference/partiallyNamedTuples.types create mode 100644 tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 41ac4b6be1a17..f2a7cc1c63ea3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -800,6 +800,7 @@ import { LiteralTypeNode, mangleScopedPackageName, map, + mapAllOrFail, mapDefined, MappedSymbol, MappedType, @@ -6884,21 +6885,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const arity = getTypeReferenceArity(type); const tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context); if (tupleConstituentNodes) { - if ((type.target as TupleType).labeledElementDeclarations) { - for (let i = 0; i < tupleConstituentNodes.length; i++) { - const flags = (type.target as TupleType).elementFlags[i]; + const { labeledElementDeclarations } = type.target as TupleType; + for (let i = 0; i < tupleConstituentNodes.length; i++) { + const flags = (type.target as TupleType).elementFlags[i]; + const labeledElementDeclaration = labeledElementDeclarations?.[i]; + + if (labeledElementDeclaration) { tupleConstituentNodes[i] = factory.createNamedTupleMember( flags & ElementFlags.Variable ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined, - factory.createIdentifier(unescapeLeadingUnderscores(getTupleElementLabel((type.target as TupleType).labeledElementDeclarations![i]))), + factory.createIdentifier(unescapeLeadingUnderscores(getTupleElementLabel(labeledElementDeclaration))), flags & ElementFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined, flags & ElementFlags.Rest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i] ); } - } - else { - for (let i = 0; i < Math.min(arity, tupleConstituentNodes.length); i++) { - const flags = (type.target as TupleType).elementFlags[i]; + else { tupleConstituentNodes[i] = flags & ElementFlags.Variable ? factory.createRestTypeNode(flags & ElementFlags.Rest ? factory.createArrayTypeNode(tupleConstituentNodes[i]) : tupleConstituentNodes[i]) : flags & ElementFlags.Optional ? factory.createOptionalTypeNode(tupleConstituentNodes[i]) : @@ -12643,19 +12644,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getExpandedParameters(sig: Signature, skipUnionExpanding?: boolean): readonly (readonly Symbol[])[] { if (signatureHasRestParameter(sig)) { const restIndex = sig.parameters.length - 1; + const restName = sig.parameters[restIndex].escapedName; const restType = getTypeOfSymbol(sig.parameters[restIndex]); if (isTupleType(restType)) { - return [expandSignatureParametersWithTupleMembers(restType, restIndex)]; + return [expandSignatureParametersWithTupleMembers(restType, restIndex, restName)]; } else if (!skipUnionExpanding && restType.flags & TypeFlags.Union && every((restType as UnionType).types, isTupleType)) { - return map((restType as UnionType).types, t => expandSignatureParametersWithTupleMembers(t as TupleTypeReference, restIndex)); + return map((restType as UnionType).types, t => expandSignatureParametersWithTupleMembers(t as TupleTypeReference, restIndex, restName)); } } return [sig.parameters]; - function expandSignatureParametersWithTupleMembers(restType: TupleTypeReference, restIndex: number) { + function expandSignatureParametersWithTupleMembers(restType: TupleTypeReference, restIndex: number, restName: __String) { const elementTypes = getTypeArguments(restType); - const associatedNames = getUniqAssociatedNamesFromTupleType(restType); + const associatedNames = getUniqAssociatedNamesFromTupleType(restType, restName); const restParams = map(elementTypes, (t, i) => { // Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name const name = associatedNames && associatedNames[i] ? associatedNames[i] : @@ -12670,10 +12672,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return concatenate(sig.parameters.slice(0, restIndex), restParams); } - function getUniqAssociatedNamesFromTupleType(type: TupleTypeReference) { + function getUniqAssociatedNamesFromTupleType(type: TupleTypeReference, restName: __String) { const associatedNamesMap = new Map<__String, number>(); - return map(type.target.labeledElementDeclarations, labeledElement => { - const name = getTupleElementLabel(labeledElement); + return map(type.target.labeledElementDeclarations, (labeledElement, i) => { + const name = getTupleElementLabel(labeledElement, i, restName); const prevCounter = associatedNamesMap.get(name); if (prevCounter === undefined) { associatedNamesMap.set(name, 1); @@ -15890,8 +15892,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return readonly ? globalReadonlyArrayType : globalArrayType; } const elementFlags = map((node as TupleTypeNode).elements, getTupleElementFlags); - const missingName = some((node as TupleTypeNode).elements, e => e.kind !== SyntaxKind.NamedTupleMember); - return getTupleTargetType(elementFlags, readonly, /*associatedNames*/ missingName ? undefined : (node as TupleTypeNode).elements as readonly NamedTupleMember[]); + return getTupleTargetType(elementFlags, readonly, map((node as TupleTypeNode).elements, memberIfLabeledElementDeclaration)); + } + + function memberIfLabeledElementDeclaration(member: Node): NamedTupleMember | ParameterDeclaration | undefined{ + return isNamedTupleMember(member) || isParameter(member) ? member : undefined; } // Return true if the given type reference node is directly aliased or if it needs to be deferred @@ -15981,21 +15986,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isTypeOperatorNode(node) && node.operator === SyntaxKind.ReadonlyKeyword; } - function createTupleType(elementTypes: readonly Type[], elementFlags?: readonly ElementFlags[], readonly = false, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]) { + function createTupleType(elementTypes: readonly Type[], elementFlags?: readonly ElementFlags[], readonly = false, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]) { const tupleTarget = getTupleTargetType(elementFlags || map(elementTypes, _ => ElementFlags.Required), readonly, namedMemberDeclarations); return tupleTarget === emptyGenericType ? emptyObjectType : elementTypes.length ? createNormalizedTypeReference(tupleTarget, elementTypes) : tupleTarget; } - function getTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]): GenericType { + function getTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]): GenericType { if (elementFlags.length === 1 && elementFlags[0] & ElementFlags.Rest) { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; } + const memberIds = namedMemberDeclarations?.length && mapAllOrFail(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + (readonly ? "R" : "") + - (namedMemberDeclarations && namedMemberDeclarations.length ? "," + map(namedMemberDeclarations, getNodeId).join(",") : ""); + (memberIds ? "," + memberIds.join(",") : ""); let type = tupleTypes.get(key); if (!type) { tupleTypes.set(key, type = createTupleTargetType(elementFlags, readonly, namedMemberDeclarations)); @@ -16010,7 +16016,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // // Note that the generic type created by this function has no symbol associated with it. The same // is true for each of the synthesized type parameters. - function createTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration)[] | undefined): TupleType { + function createTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration | undefined)[] | undefined): TupleType { const arity = elementFlags.length; const minLength = countWhere(elementFlags, f => !!(f & (ElementFlags.Required | ElementFlags.Variadic))); let typeParameters: TypeParameter[] | undefined; @@ -34513,7 +34519,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type; } - function getTupleElementLabel(d: ParameterDeclaration | NamedTupleMember) { + function getTupleElementLabel(d: ParameterDeclaration | NamedTupleMember): __String; + function getTupleElementLabel(d: ParameterDeclaration | NamedTupleMember | undefined, index: number, restParameterName?: __String): __String; + function getTupleElementLabel(d: ParameterDeclaration | NamedTupleMember | undefined, index?: number, restParameterName = "arg" as __String) { + if (!d) { + return `${restParameterName}_${index}` as __String; + } Debug.assert(isIdentifier(d.name)); // Parameter declarations could be binding patterns, but we only allow identifier names return d.name.escapedText; } @@ -34528,7 +34539,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isTupleType(restType)) { const associatedNames = ((restType as TypeReference).target as TupleType).labeledElementDeclarations; const index = pos - paramCount; - return associatedNames && getTupleElementLabel(associatedNames[index]) || restParameter.escapedName + "_" + index as __String; + return getTupleElementLabel(associatedNames?.[index], index, restParameter.escapedName); } return restParameter.escapedName; } @@ -38531,12 +38542,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const elementTypes = node.elements; let seenOptionalElement = false; let seenRestElement = false; - const hasNamedElement = some(elementTypes, isNamedTupleMember); 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; - } const flags = getTupleElementFlags(e); if (flags & ElementFlags.Variadic) { const type = getTypeFromTypeNode((e as RestTypeNode | NamedTupleMember).type); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index dedb099abfa65..e0464d3b47029 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4233,10 +4233,6 @@ "category": "Error", "code": 5083 }, - "Tuple members must all have names or all not have names.": { - "category": "Error", - "code": 5084 - }, "A tuple member cannot be both optional and rest.": { "category": "Error", "code": 5085 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 68caffea128d1..ec6900025896f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6399,7 +6399,7 @@ export interface TupleType extends GenericType { hasRestElement: boolean; combinedFlags: ElementFlags; readonly: boolean; - labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; + labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]; } export interface TupleTypeReference extends TypeReference { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 44b2efdcbfdfb..e21f4d9aff2c9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6830,7 +6830,7 @@ declare namespace ts { hasRestElement: boolean; combinedFlags: ElementFlags; readonly: boolean; - labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; + labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]; } interface TupleTypeReference extends TypeReference { target: TupleType; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d3f3c6897e489..ef9e980fc5d46 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2887,7 +2887,7 @@ declare namespace ts { hasRestElement: boolean; combinedFlags: ElementFlags; readonly: boolean; - labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; + labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]; } interface TupleTypeReference extends TypeReference { target: TupleType; diff --git a/tests/baselines/reference/namedTupleMembersErrors.errors.txt b/tests/baselines/reference/namedTupleMembersErrors.errors.txt index fe4bb2a70b078..6c147e1b8c7e5 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.errors.txt +++ b/tests/baselines/reference/namedTupleMembersErrors.errors.txt @@ -1,9 +1,3 @@ -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(1,41): error TS5084: Tuple members must all have names or all not have names. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(2,25): error TS5084: Tuple members must all have names or all not have names. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(4,32): error TS5084: Tuple members must all have names or all not have names. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(5,22): error TS5084: Tuple members must all have names or all not have names. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(7,32): error TS5084: Tuple members must all have names or all not have names. -tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(8,22): error TS5084: Tuple members must all have names or all not have names. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(10,29): error TS5086: A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(12,46): error TS5087: A labeled tuple element is declared as rest with a '...' before the name, rather than before the type. tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(14,49): error TS5087: A labeled tuple element is declared as rest with a '...' before the name, rather than before the type. @@ -14,27 +8,15 @@ tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(20,13): err tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(21,13): error TS2456: Type alias 'RecusiveRest' circularly references itself. -==== tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts (14 errors) ==== - export type Segment1 = [length: number, number]; // partially named, disallowed - ~~~~~~ -!!! error TS5084: Tuple members must all have names or all not have names. - export type Segment2 = [number, size: number]; // partially named, disallowed - ~~~~~~ -!!! error TS5084: Tuple members must all have names or all not have names. +==== tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts (8 errors) ==== + export type Segment1 = [length: number, number]; + export type Segment2 = [number, size: number]; - export type List = [item: any, ...any]; // partially named, disallowed - ~~~~~~ -!!! error TS5084: Tuple members must all have names or all not have names. - export type List2 = [any, ...remainder: any]; // partially named, disallowed - ~~~ -!!! error TS5084: Tuple members must all have names or all not have names. + export type List = [item: any, ...any]; + export type List2 = [any, ...remainder: any]; - export type Pair = [item: any, any?]; // partially named, disallowed - ~~~~ -!!! error TS5084: Tuple members must all have names or all not have names. - export type Pair2 = [any, last?: any]; // partially named, disallowed - ~~~ -!!! error TS5084: Tuple members must all have names or all not have names. + export type Pair = [item: any, any?]; + export type Pair2 = [any, last?: any]; export type Opt = [element: string?]; // question mark on element disallowed ~~~~~~~ diff --git a/tests/baselines/reference/namedTupleMembersErrors.js b/tests/baselines/reference/namedTupleMembersErrors.js index 914d2ac5fbf6d..db03846872b57 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.js +++ b/tests/baselines/reference/namedTupleMembersErrors.js @@ -1,12 +1,12 @@ //// [namedTupleMembersErrors.ts] -export type Segment1 = [length: number, number]; // partially named, disallowed -export type Segment2 = [number, size: number]; // partially named, disallowed +export type Segment1 = [length: number, number]; +export type Segment2 = [number, size: number]; -export type List = [item: any, ...any]; // partially named, disallowed -export type List2 = [any, ...remainder: any]; // partially named, disallowed +export type List = [item: any, ...any]; +export type List2 = [any, ...remainder: any]; -export type Pair = [item: any, any?]; // partially named, disallowed -export type Pair2 = [any, last?: any]; // partially named, disallowed +export type Pair = [item: any, any?]; +export type Pair2 = [any, last?: any]; export type Opt = [element: string?]; // question mark on element disallowed diff --git a/tests/baselines/reference/namedTupleMembersErrors.symbols b/tests/baselines/reference/namedTupleMembersErrors.symbols index 6040512d2da27..09820ecfb7163 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.symbols +++ b/tests/baselines/reference/namedTupleMembersErrors.symbols @@ -1,20 +1,20 @@ === tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts === -export type Segment1 = [length: number, number]; // partially named, disallowed +export type Segment1 = [length: number, number]; >Segment1 : Symbol(Segment1, Decl(namedTupleMembersErrors.ts, 0, 0)) -export type Segment2 = [number, size: number]; // partially named, disallowed +export type Segment2 = [number, size: number]; >Segment2 : Symbol(Segment2, Decl(namedTupleMembersErrors.ts, 0, 48)) -export type List = [item: any, ...any]; // partially named, disallowed +export type List = [item: any, ...any]; >List : Symbol(List, Decl(namedTupleMembersErrors.ts, 1, 46)) -export type List2 = [any, ...remainder: any]; // partially named, disallowed +export type List2 = [any, ...remainder: any]; >List2 : Symbol(List2, Decl(namedTupleMembersErrors.ts, 3, 39)) -export type Pair = [item: any, any?]; // partially named, disallowed +export type Pair = [item: any, any?]; >Pair : Symbol(Pair, Decl(namedTupleMembersErrors.ts, 4, 45)) -export type Pair2 = [any, last?: any]; // partially named, disallowed +export type Pair2 = [any, last?: any]; >Pair2 : Symbol(Pair2, Decl(namedTupleMembersErrors.ts, 6, 37)) export type Opt = [element: string?]; // question mark on element disallowed diff --git a/tests/baselines/reference/namedTupleMembersErrors.types b/tests/baselines/reference/namedTupleMembersErrors.types index a191b57a718dc..6ec0da2976bfd 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.types +++ b/tests/baselines/reference/namedTupleMembersErrors.types @@ -1,21 +1,21 @@ === tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts === -export type Segment1 = [length: number, number]; // partially named, disallowed ->Segment1 : [number, number] +export type Segment1 = [length: number, number]; +>Segment1 : [length: number, number] -export type Segment2 = [number, size: number]; // partially named, disallowed ->Segment2 : [number, number] +export type Segment2 = [number, size: number]; +>Segment2 : [length: number, number] -export type List = [item: any, ...any]; // partially named, disallowed +export type List = [item: any, ...any]; >List : [any, ...any[]] -export type List2 = [any, ...remainder: any]; // partially named, disallowed +export type List2 = [any, ...remainder: any]; >List2 : [any, ...any[]] -export type Pair = [item: any, any?]; // partially named, disallowed ->Pair : [any, any?] +export type Pair = [item: any, any?]; +>Pair : [item: any, any?] -export type Pair2 = [any, last?: any]; // partially named, disallowed ->Pair2 : [any, any?] +export type Pair2 = [any, last?: any]; +>Pair2 : [item: any, any?] export type Opt = [element: string?]; // question mark on element disallowed >Opt : [element: string] diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js new file mode 100644 index 0000000000000..a8b3288f3998d --- /dev/null +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -0,0 +1,44 @@ +//// [partiallyNamedTuples.ts] +type NamedAndAnonymous = [a: string, number]; + +function fa1(...args: NamedAndAnonymous) {} +function fa2(a: NamedAndAnonymous, ...args: NamedAndAnonymous) {} + +type NamedAnonymousMixed = [a: string, number, c: number, NamedAndAnonymous]; + +function fb1(...args: NamedAnonymousMixed) {} +function fb2(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed) {} +function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} + + +//// [partiallyNamedTuples.js] +function fa1() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } +} +function fa2(a) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } +} +function fb1() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } +} +function fb2(a) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } +} +function fb3(a) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } +} diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols new file mode 100644 index 0000000000000..b31ea8ec8cd8f --- /dev/null +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -0,0 +1,39 @@ +=== tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts === +type NamedAndAnonymous = [a: string, number]; +>NamedAndAnonymous : Symbol(NamedAndAnonymous, Decl(partiallyNamedTuples.ts, 0, 0)) + +function fa1(...args: NamedAndAnonymous) {} +>fa1 : Symbol(fa1, Decl(partiallyNamedTuples.ts, 0, 45)) +>args : Symbol(args, Decl(partiallyNamedTuples.ts, 2, 13)) +>NamedAndAnonymous : Symbol(NamedAndAnonymous, Decl(partiallyNamedTuples.ts, 0, 0)) + +function fa2(a: NamedAndAnonymous, ...args: NamedAndAnonymous) {} +>fa2 : Symbol(fa2, Decl(partiallyNamedTuples.ts, 2, 43)) +>a : Symbol(a, Decl(partiallyNamedTuples.ts, 3, 13)) +>NamedAndAnonymous : Symbol(NamedAndAnonymous, Decl(partiallyNamedTuples.ts, 0, 0)) +>args : Symbol(args, Decl(partiallyNamedTuples.ts, 3, 34)) +>NamedAndAnonymous : Symbol(NamedAndAnonymous, Decl(partiallyNamedTuples.ts, 0, 0)) + +type NamedAnonymousMixed = [a: string, number, c: number, NamedAndAnonymous]; +>NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) +>NamedAndAnonymous : Symbol(NamedAndAnonymous, Decl(partiallyNamedTuples.ts, 0, 0)) + +function fb1(...args: NamedAnonymousMixed) {} +>fb1 : Symbol(fb1, Decl(partiallyNamedTuples.ts, 5, 77)) +>args : Symbol(args, Decl(partiallyNamedTuples.ts, 7, 13)) +>NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) + +function fb2(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed) {} +>fb2 : Symbol(fb2, Decl(partiallyNamedTuples.ts, 7, 45)) +>a : Symbol(a, Decl(partiallyNamedTuples.ts, 8, 13)) +>NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) +>args : Symbol(args, Decl(partiallyNamedTuples.ts, 8, 36)) +>NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) + +function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} +>fb3 : Symbol(fb3, Decl(partiallyNamedTuples.ts, 8, 69)) +>a : Symbol(a, Decl(partiallyNamedTuples.ts, 9, 13)) +>NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) +>args : Symbol(args, Decl(partiallyNamedTuples.ts, 9, 36)) +>NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) + diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types new file mode 100644 index 0000000000000..933b8474831d3 --- /dev/null +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts === +type NamedAndAnonymous = [a: string, number]; +>NamedAndAnonymous : [a: string, number] + +function fa1(...args: NamedAndAnonymous) {} +>fa1 : (a: string, args_1: number) => void +>args : NamedAndAnonymous + +function fa2(a: NamedAndAnonymous, ...args: NamedAndAnonymous) {} +>fa2 : (a: NamedAndAnonymous, a: string, args_1: number) => void +>a : NamedAndAnonymous +>args : NamedAndAnonymous + +type NamedAnonymousMixed = [a: string, number, c: number, NamedAndAnonymous]; +>NamedAnonymousMixed : [a: string, number, c: number, NamedAndAnonymous] + +function fb1(...args: NamedAnonymousMixed) {} +>fb1 : (a: string, args_1: number, c: number, args_3: NamedAndAnonymous) => void +>args : NamedAnonymousMixed + +function fb2(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed) {} +>fb2 : (a: NamedAnonymousMixed, a: string, args_1: number, c: number, args_3: NamedAndAnonymous) => void +>a : NamedAnonymousMixed +>args : NamedAnonymousMixed + +function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} +>fb3 : (a: NamedAnonymousMixed, a: string, args_1: number) => void +>a : NamedAnonymousMixed +>args : NamedAndAnonymous + diff --git a/tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts b/tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts index 6a1f5a0537085..ecd90aebd7ddd 100644 --- a/tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts +++ b/tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts @@ -1,13 +1,13 @@ // @declaration: true -export type Segment1 = [length: number, number]; // partially named, disallowed -export type Segment2 = [number, size: number]; // partially named, disallowed +export type Segment1 = [length: number, number]; +export type Segment2 = [number, size: number]; -export type List = [item: any, ...any]; // partially named, disallowed -export type List2 = [any, ...remainder: any]; // partially named, disallowed +export type List = [item: any, ...any]; +export type List2 = [any, ...remainder: any]; -export type Pair = [item: any, any?]; // partially named, disallowed -export type Pair2 = [any, last?: any]; // partially named, disallowed +export type Pair = [item: any, any?]; +export type Pair2 = [any, last?: any]; export type Opt = [element: string?]; // question mark on element disallowed diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts new file mode 100644 index 0000000000000..d4cd5c5cfcc21 --- /dev/null +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -0,0 +1,10 @@ +type NamedAndAnonymous = [a: string, number]; + +function fa1(...args: NamedAndAnonymous) {} +function fa2(a: NamedAndAnonymous, ...args: NamedAndAnonymous) {} + +type NamedAnonymousMixed = [a: string, number, c: number, NamedAndAnonymous]; + +function fb1(...args: NamedAnonymousMixed) {} +function fb2(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed) {} +function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} From 2c316ce63cce9ec95ec6cb870d857c8c53efa29b Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 22 Mar 2023 18:10:57 -0400 Subject: [PATCH 02/16] What a fun little caching issue --- src/compiler/checker.ts | 3 +-- tests/baselines/reference/namedTupleMembersErrors.types | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f2a7cc1c63ea3..32ce617dd6f87 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -800,7 +800,6 @@ import { LiteralTypeNode, mangleScopedPackageName, map, - mapAllOrFail, mapDefined, MappedSymbol, MappedType, @@ -15998,7 +15997,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; } - const memberIds = namedMemberDeclarations?.length && mapAllOrFail(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); + const memberIds = namedMemberDeclarations?.length && map(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + (readonly ? "R" : "") + (memberIds ? "," + memberIds.join(",") : ""); diff --git a/tests/baselines/reference/namedTupleMembersErrors.types b/tests/baselines/reference/namedTupleMembersErrors.types index 6ec0da2976bfd..459abe94e7729 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.types +++ b/tests/baselines/reference/namedTupleMembersErrors.types @@ -3,7 +3,7 @@ export type Segment1 = [length: number, number]; >Segment1 : [length: number, number] export type Segment2 = [number, size: number]; ->Segment2 : [length: number, number] +>Segment2 : [number, size: number] export type List = [item: any, ...any]; >List : [any, ...any[]] @@ -15,7 +15,7 @@ export type Pair = [item: any, any?]; >Pair : [item: any, any?] export type Pair2 = [any, last?: any]; ->Pair2 : [item: any, any?] +>Pair2 : [any, last?: any] export type Opt = [element: string?]; // question mark on element disallowed >Opt : [element: string] From d246ce999b09600573e6e7bd890bed34ab2da13d Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Mar 2023 12:05:51 -0400 Subject: [PATCH 03/16] fix: it's any member being defined, not the array length --- src/compiler/checker.ts | 3 ++- src/compiler/core.ts | 5 +++++ src/services/callHierarchy.ts | 5 +---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32ce617dd6f87..b754325513b04 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1066,6 +1066,7 @@ import { WideningContext, WithStatement, YieldExpression, + isDefined, } from "./_namespaces/ts"; import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; import * as performance from "./_namespaces/ts.performance"; @@ -15997,7 +15998,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; } - const memberIds = namedMemberDeclarations?.length && map(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); + const memberIds = some(namedMemberDeclarations, isDefined) && map(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + (readonly ? "R" : "") + (memberIds ? "," + memberIds.join(",") : ""); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 1acb342daa494..a16a77007bddf 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2833,6 +2833,11 @@ export function skipWhile(array: readonly T[] | undefined, predi } } +/** @internal */ +export function isDefined(x: T): x is NonNullable { + return x !== undefined; +} + /** * Removes the leading and trailing white space and line terminator characters from a string. * diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index a2d32e6da717f..c574b7e76676e 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -58,6 +58,7 @@ import { isConstructorDeclaration, isDeclarationName, isDecoratorTarget, + isDefined, isFunctionDeclaration, isFunctionExpression, isFunctionLikeDeclaration, @@ -420,10 +421,6 @@ export function createCallHierarchyItem(program: Program, node: CallHierarchyDec return { file: sourceFile.fileName, kind, kindModifiers, name: name.text, containerName, span, selectionSpan }; } -function isDefined(x: T): x is NonNullable { - return x !== undefined; -} - interface CallSite { declaration: CallHierarchyDeclaration; range: TextRange; From c5efef9b3e4ae6d07e13c326bf2269813a8e73b9 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Mar 2023 12:09:28 -0400 Subject: [PATCH 04/16] Lint fix --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b754325513b04..29f255609a646 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -486,6 +486,7 @@ import { isDeclarationReadonly, isDecorator, isDefaultedExpandoInitializer, + isDefined, isDeleteTarget, isDottedName, isDynamicName, @@ -1066,7 +1067,6 @@ import { WideningContext, WithStatement, YieldExpression, - isDefined, } from "./_namespaces/ts"; import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; import * as performance from "./_namespaces/ts.performance"; From 9859f6aa4f57119726d6373dff2fb438b5344c10 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Mar 2023 12:33:30 -0400 Subject: [PATCH 05/16] Switch to mapDefined, very nice Co-authored-by: Jake Bailey --- src/compiler/checker.ts | 3 +-- src/compiler/core.ts | 5 ----- src/services/callHierarchy.ts | 5 ++++- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 29f255609a646..68ca4c0ec9dfe 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -486,7 +486,6 @@ import { isDeclarationReadonly, isDecorator, isDefaultedExpandoInitializer, - isDefined, isDeleteTarget, isDottedName, isDynamicName, @@ -15998,7 +15997,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; } - const memberIds = some(namedMemberDeclarations, isDefined) && map(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); + const memberIds = mapDefined(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + (readonly ? "R" : "") + (memberIds ? "," + memberIds.join(",") : ""); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index a16a77007bddf..1acb342daa494 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2833,11 +2833,6 @@ export function skipWhile(array: readonly T[] | undefined, predi } } -/** @internal */ -export function isDefined(x: T): x is NonNullable { - return x !== undefined; -} - /** * Removes the leading and trailing white space and line terminator characters from a string. * diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts index c574b7e76676e..a2d32e6da717f 100644 --- a/src/services/callHierarchy.ts +++ b/src/services/callHierarchy.ts @@ -58,7 +58,6 @@ import { isConstructorDeclaration, isDeclarationName, isDecoratorTarget, - isDefined, isFunctionDeclaration, isFunctionExpression, isFunctionLikeDeclaration, @@ -421,6 +420,10 @@ export function createCallHierarchyItem(program: Program, node: CallHierarchyDec return { file: sourceFile.fileName, kind, kindModifiers, name: name.text, containerName, span, selectionSpan }; } +function isDefined(x: T): x is NonNullable { + return x !== undefined; +} + interface CallSite { declaration: CallHierarchyDeclaration; range: TextRange; From 99c4a01aa033001ec6ddd468d631e80c1bd2ad6b Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Mar 2023 12:48:45 -0400 Subject: [PATCH 06/16] Clear mapDefined result Co-authored-by: Jake Bailey --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 68ca4c0ec9dfe..fd72d618eeeba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16000,7 +16000,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const memberIds = mapDefined(namedMemberDeclarations, node => node ? getNodeId(node) : undefined); const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() + (readonly ? "R" : "") + - (memberIds ? "," + memberIds.join(",") : ""); + (memberIds.length ? "," + memberIds.join(",") : ""); let type = tupleTypes.get(key); if (!type) { tupleTypes.set(key, type = createTupleTargetType(elementFlags, readonly, namedMemberDeclarations)); From c3c2da32f0f1ee8e34817269b9243e5f9be7cd12 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 26 Mar 2023 15:03:59 -0400 Subject: [PATCH 07/16] More baselines --- .../reference/partiallyNamedTuples.js | 29 +++++++ .../reference/partiallyNamedTuples.symbols | 83 +++++++++++++++++++ .../reference/partiallyNamedTuples.types | 51 ++++++++++++ .../types/tuple/named/partiallyNamedTuples.ts | 29 +++++++ 4 files changed, 192 insertions(+) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index a8b3288f3998d..d4b59cf9ce467 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -9,6 +9,35 @@ type NamedAnonymousMixed = [a: string, number, c: number, NamedAndAnonymous]; function fb1(...args: NamedAnonymousMixed) {} function fb2(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed) {} function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} + +type ToAnonymousTuple = { + [K in keyof T]: [K, T[K], keyof T, T]; +}; + +type AnonymousToAnonymous = ToAnonymousTuple<[boolean, number]>; +type MixedToAnonymous = ToAnonymousTuple<[boolean, second: number]>; +type NamedToAnonymous = ToAnonymousTuple<[first: boolean, second: number]>; + +type ToMixedTuple = { + [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; +}; + +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; + +type MixedSpread = [first: boolean, ...[second: string]]; + +type AddMixedConditional = [ + first: boolean, + null, + third: T extends number ? "a" : "b", + ...(T extends 0 ? [fourth: "c"] : []) +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +type AddMixedConditionalLiteral = AddMixedConditional<0>; +type AddMixedConditionalNumberPrimitive = AddMixedConditional; //// [partiallyNamedTuples.js] diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index b31ea8ec8cd8f..4b20799d118da 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -37,3 +37,86 @@ function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} >args : Symbol(args, Decl(partiallyNamedTuples.ts, 9, 36)) >NamedAnonymousMixed : Symbol(NamedAnonymousMixed, Decl(partiallyNamedTuples.ts, 3, 65)) +type ToAnonymousTuple = { +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 11, 22)) + + [K in keyof T]: [K, T[K], keyof T, T]; +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 12, 3)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 11, 22)) +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 12, 3)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 11, 22)) +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 12, 3)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 11, 22)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 11, 22)) + +}; + +type AnonymousToAnonymous = ToAnonymousTuple<[boolean, number]>; +>AnonymousToAnonymous : Symbol(AnonymousToAnonymous, Decl(partiallyNamedTuples.ts, 13, 2)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) + +type MixedToAnonymous = ToAnonymousTuple<[boolean, second: number]>; +>MixedToAnonymous : Symbol(MixedToAnonymous, Decl(partiallyNamedTuples.ts, 15, 64)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) + +type NamedToAnonymous = ToAnonymousTuple<[first: boolean, second: number]>; +>NamedToAnonymous : Symbol(NamedToAnonymous, Decl(partiallyNamedTuples.ts, 16, 68)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) + +type ToMixedTuple = { +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 19, 18)) + + [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 20, 3)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 19, 18)) +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 20, 3)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 19, 18)) +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 20, 3)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 19, 18)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 19, 18)) + +}; + +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +>AnonymousToMixed : Symbol(AnonymousToMixed, Decl(partiallyNamedTuples.ts, 21, 2)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) + +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +>MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 60)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) + +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +>NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 64)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) + +type MixedSpread = [first: boolean, ...[second: string]]; +>MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 71)) + +type AddMixedConditional = [ +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 29, 25)) + + first: boolean, + null, + third: T extends number ? "a" : "b", +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 29, 25)) + + ...(T extends 0 ? [fourth: "c"] : []) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 29, 25)) + +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +>AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 34, 2)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) + +type AddMixedConditionalLiteral = AddMixedConditional<0>; +>AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 36, 63)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) + +type AddMixedConditionalNumberPrimitive = AddMixedConditional; +>AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 37, 57)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) + diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index 933b8474831d3..6cb6c84e499bc 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -28,3 +28,54 @@ function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} >a : NamedAnonymousMixed >args : NamedAndAnonymous +type ToAnonymousTuple = { +>ToAnonymousTuple : ToAnonymousTuple + + [K in keyof T]: [K, T[K], keyof T, T]; +}; + +type AnonymousToAnonymous = ToAnonymousTuple<[boolean, number]>; +>AnonymousToAnonymous : [["0", boolean, keyof [boolean, number], [boolean, number]], ["1", number, keyof [boolean, number], [boolean, number]]] + +type MixedToAnonymous = ToAnonymousTuple<[boolean, second: number]>; +>MixedToAnonymous : [["0", boolean, keyof [boolean, second: number], [boolean, second: number]], second: ["1", number, keyof [boolean, second: number], [boolean, second: number]]] + +type NamedToAnonymous = ToAnonymousTuple<[first: boolean, second: number]>; +>NamedToAnonymous : [first: ["0", boolean, keyof [first: boolean, second: number], [first: boolean, second: number]], second: ["1", number, keyof [first: boolean, second: number], [first: boolean, second: number]]] + +type ToMixedTuple = { +>ToMixedTuple : ToMixedTuple + + [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; +}; + +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +>AnonymousToMixed : [["0", boolean, keyof [boolean, number], [boolean, number]], ["1", number, keyof [boolean, number], [boolean, number]]] + +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +>MixedToMixed : [["0", boolean, keyof [boolean, second: number], [boolean, second: number]], second: ["1", number, keyof [boolean, second: number], [boolean, second: number]]] + +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +>NamedToMixed : [first: ["0", boolean, keyof [first: boolean, second: number], [first: boolean, second: number]], second: ["1", number, keyof [first: boolean, second: number], [first: boolean, second: number]]] + +type MixedSpread = [first: boolean, ...[second: string]]; +>MixedSpread : [first: boolean, second: string] + +type AddMixedConditional = [ +>AddMixedConditional : [boolean, null, T extends number ? "a" : "b", ...T extends 0 ? [fourth: "c"] : []] + + first: boolean, + null, + third: T extends number ? "a" : "b", + ...(T extends 0 ? [fourth: "c"] : []) +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +>AddMixedConditionalBoolean : [boolean, null, "b"] + +type AddMixedConditionalLiteral = AddMixedConditional<0>; +>AddMixedConditionalLiteral : [boolean, null, "a", "c"] + +type AddMixedConditionalNumberPrimitive = AddMixedConditional; +>AddMixedConditionalNumberPrimitive : [boolean, null, "a"] + diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index d4cd5c5cfcc21..cdc0bd7d7bb79 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -8,3 +8,32 @@ type NamedAnonymousMixed = [a: string, number, c: number, NamedAndAnonymous]; function fb1(...args: NamedAnonymousMixed) {} function fb2(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed) {} function fb3(a: NamedAnonymousMixed, ...args: NamedAnonymousMixed[3]) {} + +type ToAnonymousTuple = { + [K in keyof T]: [K, T[K], keyof T, T]; +}; + +type AnonymousToAnonymous = ToAnonymousTuple<[boolean, number]>; +type MixedToAnonymous = ToAnonymousTuple<[boolean, second: number]>; +type NamedToAnonymous = ToAnonymousTuple<[first: boolean, second: number]>; + +type ToMixedTuple = { + [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; +}; + +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; + +type MixedSpread = [first: boolean, ...[second: string]]; + +type AddMixedConditional = [ + first: boolean, + null, + third: T extends number ? "a" : "b", + ...(T extends 0 ? [fourth: "c"] : []) +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +type AddMixedConditionalLiteral = AddMixedConditional<0>; +type AddMixedConditionalNumberPrimitive = AddMixedConditional; From c994d4bb644a71cae553bc30fb140df3802fc9d7 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 26 Mar 2023 15:09:08 -0400 Subject: [PATCH 08/16] Added ConditionalTuple test case --- .../reference/partiallyNamedTuples.js | 6 ++++ .../reference/partiallyNamedTuples.symbols | 28 ++++++++++++------- .../reference/partiallyNamedTuples.types | 8 ++++++ .../types/tuple/named/partiallyNamedTuples.ts | 6 ++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index d4b59cf9ce467..954b9c57931a6 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -28,6 +28,12 @@ type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; +type ConditionalTuple = [ + // ^? + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + type AddMixedConditional = [ first: boolean, null, diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index 4b20799d118da..7591b8d39a449 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -94,29 +94,37 @@ type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; >MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 71)) +type ConditionalTuple = [ +>ConditionalTuple : Symbol(ConditionalTuple, Decl(partiallyNamedTuples.ts, 27, 57)) + + // ^? + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + type AddMixedConditional = [ ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 29, 25)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 35, 25)) first: boolean, null, third: T extends number ? "a" : "b", ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 29, 25)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 35, 25)) ...(T extends 0 ? [fourth: "c"] : []) ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 29, 25)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 35, 25)) ]; type AddMixedConditionalBoolean = AddMixedConditional; ->AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 34, 2)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) +>AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 40, 2)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) type AddMixedConditionalLiteral = AddMixedConditional<0>; ->AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 36, 63)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) +>AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 42, 63)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) type AddMixedConditionalNumberPrimitive = AddMixedConditional; ->AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 37, 57)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 27, 57)) +>AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 43, 57)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index 6cb6c84e499bc..b7c8ddc725321 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -61,6 +61,14 @@ type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; >MixedSpread : [first: boolean, second: string] +type ConditionalTuple = [ +>ConditionalTuple : [first: boolean, second: string] + + // ^? + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + type AddMixedConditional = [ >AddMixedConditional : [boolean, null, T extends number ? "a" : "b", ...T extends 0 ? [fourth: "c"] : []] diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index cdc0bd7d7bb79..e6e40c79fc172 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -27,6 +27,12 @@ type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; +type ConditionalTuple = [ + // ^? + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + type AddMixedConditional = [ first: boolean, null, From 31f493ac9b1d9db5f7bf66fd4b6214e3c7fc7a23 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 26 Mar 2023 15:09:22 -0400 Subject: [PATCH 09/16] without ^? --- .../cases/conformance/types/tuple/named/partiallyNamedTuples.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index e6e40c79fc172..60d926cd162a7 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -28,7 +28,6 @@ type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; type ConditionalTuple = [ - // ^? first: boolean, ...(0 extends 0 ? [second: string] : []) ]; From df397a7b94aac8821c06fcc3244fef6589ae582f Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 26 Mar 2023 15:09:36 -0400 Subject: [PATCH 10/16] accept baselines --- .../reference/partiallyNamedTuples.js | 1 - .../reference/partiallyNamedTuples.symbols | 21 +++++++++---------- .../reference/partiallyNamedTuples.types | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index 954b9c57931a6..b57b6259de30c 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -29,7 +29,6 @@ type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; type ConditionalTuple = [ - // ^? first: boolean, ...(0 extends 0 ? [second: string] : []) ]; diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index 7591b8d39a449..cca1c59f27269 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -97,34 +97,33 @@ type MixedSpread = [first: boolean, ...[second: string]]; type ConditionalTuple = [ >ConditionalTuple : Symbol(ConditionalTuple, Decl(partiallyNamedTuples.ts, 27, 57)) - // ^? first: boolean, ...(0 extends 0 ? [second: string] : []) ]; type AddMixedConditional = [ ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 35, 25)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) first: boolean, null, third: T extends number ? "a" : "b", ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 35, 25)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) ...(T extends 0 ? [fourth: "c"] : []) ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 35, 25)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) ]; type AddMixedConditionalBoolean = AddMixedConditional; ->AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 40, 2)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) +>AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 39, 2)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) type AddMixedConditionalLiteral = AddMixedConditional<0>; ->AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 42, 63)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) +>AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 41, 63)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) type AddMixedConditionalNumberPrimitive = AddMixedConditional; ->AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 43, 57)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 33, 2)) +>AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 42, 57)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index b7c8ddc725321..45d0b64f269e2 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -64,7 +64,6 @@ type MixedSpread = [first: boolean, ...[second: string]]; type ConditionalTuple = [ >ConditionalTuple : [first: boolean, second: string] - // ^? first: boolean, ...(0 extends 0 ? [second: string] : []) ]; From bf4b8cb1ba7ad1f4979e0c1cff8d8f2a6db2ed6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 27 Mar 2023 13:22:04 +0200 Subject: [PATCH 11/16] Keep partial labels in `createTupleTargetType` --- src/compiler/checker.ts | 17 ++++++----------- .../reference/genericRestParameters2.types | 2 +- .../reference/genericRestParameters3.types | 8 ++++---- ...ithFixedTupleExtendsAtVariadicPosition.types | 4 ++-- .../reference/namedTupleMembersErrors.types | 4 ++-- .../reference/partiallyNamedTuples.types | 8 ++++---- 6 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fd72d618eeeba..65abc23699007 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15985,14 +15985,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isTypeOperatorNode(node) && node.operator === SyntaxKind.ReadonlyKeyword; } - function createTupleType(elementTypes: readonly Type[], elementFlags?: readonly ElementFlags[], readonly = false, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]) { + function createTupleType(elementTypes: readonly Type[], elementFlags?: readonly ElementFlags[], readonly = false, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration | undefined)[] = []) { const tupleTarget = getTupleTargetType(elementFlags || map(elementTypes, _ => ElementFlags.Required), readonly, namedMemberDeclarations); return tupleTarget === emptyGenericType ? emptyObjectType : elementTypes.length ? createNormalizedTypeReference(tupleTarget, elementTypes) : tupleTarget; } - function getTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations?: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]): GenericType { + function getTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]): GenericType { if (elementFlags.length === 1 && elementFlags[0] & ElementFlags.Rest) { // [...X[]] is equivalent to just X[] return readonly ? globalReadonlyArrayType : globalArrayType; @@ -16015,7 +16015,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // // Note that the generic type created by this function has no symbol associated with it. The same // is true for each of the synthesized type parameters. - function createTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration | undefined)[] | undefined): TupleType { + function createTupleTargetType(elementFlags: readonly ElementFlags[], readonly: boolean, namedMemberDeclarations: readonly (NamedTupleMember | ParameterDeclaration | undefined)[]): TupleType { const arity = elementFlags.length; const minLength = countWhere(elementFlags, f => !!(f & (ElementFlags.Required | ElementFlags.Variadic))); let typeParameters: TypeParameter[] | undefined; @@ -16097,7 +16097,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // 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 = []; + const expandedDeclarations: (NamedTupleMember | ParameterDeclaration | undefined)[] = []; let lastRequiredIndex = -1; let firstRestIndex = -1; let lastOptionalOrRestIndex = -1; @@ -16140,7 +16140,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { (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); + expandedDeclarations.splice(firstRestIndex + 1, lastOptionalOrRestIndex - firstRestIndex); } const tupleTarget = getTupleTargetType(expandedFlags, target.readonly, expandedDeclarations); return tupleTarget === emptyGenericType ? emptyObjectType : @@ -16159,12 +16159,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } expandedTypes.push(flags & ElementFlags.Optional ? addOptionality(type, /*isProperty*/ true) : type); expandedFlags.push(flags); - if (expandedDeclarations && declaration) { - expandedDeclarations.push(declaration); - } - else { - expandedDeclarations = undefined; - } + expandedDeclarations.push(declaration); } } diff --git a/tests/baselines/reference/genericRestParameters2.types b/tests/baselines/reference/genericRestParameters2.types index ed4555c93694f..ff6f878efd8a0 100644 --- a/tests/baselines/reference/genericRestParameters2.types +++ b/tests/baselines/reference/genericRestParameters2.types @@ -442,7 +442,7 @@ type T05 = Parameters<(x: string, ...args: T) => void>; >args : T type T06 = T05<[number, ...boolean[]]>; ->T06 : [string, number, ...boolean[]] +>T06 : [x: string, number, ...boolean[]] type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; >P1 : P1 diff --git a/tests/baselines/reference/genericRestParameters3.types b/tests/baselines/reference/genericRestParameters3.types index d582932ba8124..b634883b71bb5 100644 --- a/tests/baselines/reference/genericRestParameters3.types +++ b/tests/baselines/reference/genericRestParameters3.types @@ -262,19 +262,19 @@ ff2 = ff1; function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) { >ff3 : (s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) => void >s1 : (...args: [x: string, ...rest: A | [number]]) => void ->args : [string, number] | [x: string, ...rest: A] +>args : [x: string, number] | [x: string, ...rest: A] >s2 : (x: string, ...rest: A | [number]) => void >x : string >rest : [number] | A s1 = s2; >s1 = s2 : (x: string, ...rest: [number] | A) => void ->s1 : (...args: [string, number] | [x: string, ...rest: A]) => void +>s1 : (...args: [x: string, number] | [x: string, ...rest: A]) => void >s2 : (x: string, ...rest: [number] | A) => void s2 = s1; ->s2 = s1 : (...args: [string, number] | [x: string, ...rest: A]) => void +>s2 = s1 : (...args: [x: string, number] | [x: string, ...rest: A]) => void >s2 : (x: string, ...rest: [number] | A) => void ->s1 : (...args: [string, number] | [x: string, ...rest: A]) => void +>s1 : (...args: [x: string, number] | [x: string, ...rest: A]) => void } diff --git a/tests/baselines/reference/inferTypesWithFixedTupleExtendsAtVariadicPosition.types b/tests/baselines/reference/inferTypesWithFixedTupleExtendsAtVariadicPosition.types index 416958583480a..127d5dcee867d 100644 --- a/tests/baselines/reference/inferTypesWithFixedTupleExtendsAtVariadicPosition.types +++ b/tests/baselines/reference/inferTypesWithFixedTupleExtendsAtVariadicPosition.types @@ -38,7 +38,7 @@ type SubTup2VariadicAndRest = T extends [ : never; type SubTup2VariadicAndRestTest = SubTup2VariadicAndRest<[a: 0, b: 1, ...c: 2[]]>; ->SubTup2VariadicAndRestTest : [0, 1, 2] +>SubTup2VariadicAndRestTest : [a: 0, b: 1, 2] type SubTup2TrailingVariadic = T extends [ >SubTup2TrailingVariadic : SubTup2TrailingVariadic @@ -65,7 +65,7 @@ type SubTup2RestAndTrailingVariadic2 = T extends [ : never; type SubTup2RestAndTrailingVariadic2Test = SubTup2RestAndTrailingVariadic2<[...a: 0[], b: 1, c: 2]>; ->SubTup2RestAndTrailingVariadic2Test : [0, 1, 2] +>SubTup2RestAndTrailingVariadic2Test : [0, b: 1, c: 2] type SubTup2VariadicWithLeadingFixedElements = T extends [ >SubTup2VariadicWithLeadingFixedElements : SubTup2VariadicWithLeadingFixedElements diff --git a/tests/baselines/reference/namedTupleMembersErrors.types b/tests/baselines/reference/namedTupleMembersErrors.types index 459abe94e7729..e3df3b40e39f1 100644 --- a/tests/baselines/reference/namedTupleMembersErrors.types +++ b/tests/baselines/reference/namedTupleMembersErrors.types @@ -6,10 +6,10 @@ export type Segment2 = [number, size: number]; >Segment2 : [number, size: number] export type List = [item: any, ...any]; ->List : [any, ...any[]] +>List : [item: any, ...any[]] export type List2 = [any, ...remainder: any]; ->List2 : [any, ...any[]] +>List2 : [any, ...remainder: any[]] export type Pair = [item: any, any?]; >Pair : [item: any, any?] diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index 45d0b64f269e2..3c04d3c564c03 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -69,7 +69,7 @@ type ConditionalTuple = [ ]; type AddMixedConditional = [ ->AddMixedConditional : [boolean, null, T extends number ? "a" : "b", ...T extends 0 ? [fourth: "c"] : []] +>AddMixedConditional : [first: boolean, null, third: T extends number ? "a" : "b", ...T extends 0 ? [fourth: "c"] : []] first: boolean, null, @@ -78,11 +78,11 @@ type AddMixedConditional = [ ]; type AddMixedConditionalBoolean = AddMixedConditional; ->AddMixedConditionalBoolean : [boolean, null, "b"] +>AddMixedConditionalBoolean : [first: boolean, null, third: "b"] type AddMixedConditionalLiteral = AddMixedConditional<0>; ->AddMixedConditionalLiteral : [boolean, null, "a", "c"] +>AddMixedConditionalLiteral : [first: boolean, null, third: "a", fourth: "c"] type AddMixedConditionalNumberPrimitive = AddMixedConditional; ->AddMixedConditionalNumberPrimitive : [boolean, null, "a"] +>AddMixedConditionalNumberPrimitive : [first: boolean, null, third: "a"] From 796ec068577cbb38fbd859d934db5ea44e268c2f Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 27 Mar 2023 10:13:20 -0400 Subject: [PATCH 12/16] Remove redundant tests --- .../reference/partiallyNamedTuples.js | 22 ++------ .../reference/partiallyNamedTuples.symbols | 51 ++++--------------- .../reference/partiallyNamedTuples.types | 37 +++----------- .../types/tuple/named/partiallyNamedTuples.ts | 22 ++------ 4 files changed, 21 insertions(+), 111 deletions(-) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index b57b6259de30c..a2d025dd6e70b 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -22,27 +22,11 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; - -type ConditionalTuple = [ - first: boolean, - ...(0 extends 0 ? [second: string] : []) -]; - -type AddMixedConditional = [ - first: boolean, - null, - third: T extends number ? "a" : "b", - ...(T extends 0 ? [fourth: "c"] : []) -]; - -type AddMixedConditionalBoolean = AddMixedConditional; -type AddMixedConditionalLiteral = AddMixedConditional<0>; -type AddMixedConditionalNumberPrimitive = AddMixedConditional; //// [partiallyNamedTuples.js] diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index cca1c59f27269..d333036c6f893 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -79,51 +79,18 @@ type ToMixedTuple = { }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; >AnonymousToMixed : Symbol(AnonymousToMixed, Decl(partiallyNamedTuples.ts, 21, 2)) ->ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; ->MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 60)) ->ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +>MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 56)) +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; ->NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 64)) ->ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; +>NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 60)) +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) type MixedSpread = [first: boolean, ...[second: string]]; ->MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 71)) - -type ConditionalTuple = [ ->ConditionalTuple : Symbol(ConditionalTuple, Decl(partiallyNamedTuples.ts, 27, 57)) - - first: boolean, - ...(0 extends 0 ? [second: string] : []) -]; - -type AddMixedConditional = [ ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) - - first: boolean, - null, - third: T extends number ? "a" : "b", ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) - - ...(T extends 0 ? [fourth: "c"] : []) ->T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) - -]; - -type AddMixedConditionalBoolean = AddMixedConditional; ->AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 39, 2)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) - -type AddMixedConditionalLiteral = AddMixedConditional<0>; ->AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 41, 63)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) - -type AddMixedConditionalNumberPrimitive = AddMixedConditional; ->AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 42, 57)) ->AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) +>MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 67)) diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index 3c04d3c564c03..d98ed8106dfa2 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -49,40 +49,15 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; ->AnonymousToMixed : [["0", boolean, keyof [boolean, number], [boolean, number]], ["1", number, keyof [boolean, number], [boolean, number]]] +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +>AnonymousToMixed : [["0", second: boolean, keyof [boolean, number], fourth: [boolean, number]], ["1", second: number, keyof [boolean, number], fourth: [boolean, number]]] -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; ->MixedToMixed : [["0", boolean, keyof [boolean, second: number], [boolean, second: number]], second: ["1", number, keyof [boolean, second: number], [boolean, second: number]]] +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +>MixedToMixed : [["0", second: boolean, keyof [boolean, second: number], fourth: [boolean, second: number]], second: ["1", second: number, keyof [boolean, second: number], fourth: [boolean, second: number]]] -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; ->NamedToMixed : [first: ["0", boolean, keyof [first: boolean, second: number], [first: boolean, second: number]], second: ["1", number, keyof [first: boolean, second: number], [first: boolean, second: number]]] +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; +>NamedToMixed : [first: ["0", second: boolean, keyof [first: boolean, second: number], fourth: [first: boolean, second: number]], second: ["1", second: number, keyof [first: boolean, second: number], fourth: [first: boolean, second: number]]] type MixedSpread = [first: boolean, ...[second: string]]; >MixedSpread : [first: boolean, second: string] -type ConditionalTuple = [ ->ConditionalTuple : [first: boolean, second: string] - - first: boolean, - ...(0 extends 0 ? [second: string] : []) -]; - -type AddMixedConditional = [ ->AddMixedConditional : [first: boolean, null, third: T extends number ? "a" : "b", ...T extends 0 ? [fourth: "c"] : []] - - first: boolean, - null, - third: T extends number ? "a" : "b", - ...(T extends 0 ? [fourth: "c"] : []) -]; - -type AddMixedConditionalBoolean = AddMixedConditional; ->AddMixedConditionalBoolean : [first: boolean, null, third: "b"] - -type AddMixedConditionalLiteral = AddMixedConditional<0>; ->AddMixedConditionalLiteral : [first: boolean, null, third: "a", fourth: "c"] - -type AddMixedConditionalNumberPrimitive = AddMixedConditional; ->AddMixedConditionalNumberPrimitive : [first: boolean, null, third: "a"] - diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index 60d926cd162a7..ecce3c22ce35d 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -21,24 +21,8 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; - -type ConditionalTuple = [ - first: boolean, - ...(0 extends 0 ? [second: string] : []) -]; - -type AddMixedConditional = [ - first: boolean, - null, - third: T extends number ? "a" : "b", - ...(T extends 0 ? [fourth: "c"] : []) -]; - -type AddMixedConditionalBoolean = AddMixedConditional; -type AddMixedConditionalLiteral = AddMixedConditional<0>; -type AddMixedConditionalNumberPrimitive = AddMixedConditional; From ffcfc79758f6d07f035483cf6c26c7c98d26f666 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 27 Mar 2023 14:11:27 -0400 Subject: [PATCH 13/16] Revert "Remove redundant tests" This reverts commit 796ec068577cbb38fbd859d934db5ea44e268c2f. --- .../reference/partiallyNamedTuples.js | 22 ++++++-- .../reference/partiallyNamedTuples.symbols | 51 +++++++++++++++---- .../reference/partiallyNamedTuples.types | 37 +++++++++++--- .../types/tuple/named/partiallyNamedTuples.ts | 22 ++++++-- 4 files changed, 111 insertions(+), 21 deletions(-) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index a2d025dd6e70b..b57b6259de30c 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -22,11 +22,27 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToMixedTuple<[boolean, number]>; -type MixedToMixed = ToMixedTuple<[boolean, second: number]>; -type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; + +type ConditionalTuple = [ + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + +type AddMixedConditional = [ + first: boolean, + null, + third: T extends number ? "a" : "b", + ...(T extends 0 ? [fourth: "c"] : []) +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +type AddMixedConditionalLiteral = AddMixedConditional<0>; +type AddMixedConditionalNumberPrimitive = AddMixedConditional; //// [partiallyNamedTuples.js] diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index d333036c6f893..cca1c59f27269 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -79,18 +79,51 @@ type ToMixedTuple = { }; -type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; >AnonymousToMixed : Symbol(AnonymousToMixed, Decl(partiallyNamedTuples.ts, 21, 2)) ->ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) -type MixedToMixed = ToMixedTuple<[boolean, second: number]>; ->MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 56)) ->ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +>MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 60)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) -type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; ->NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 60)) ->ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +>NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 64)) +>ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) type MixedSpread = [first: boolean, ...[second: string]]; ->MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 67)) +>MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 71)) + +type ConditionalTuple = [ +>ConditionalTuple : Symbol(ConditionalTuple, Decl(partiallyNamedTuples.ts, 27, 57)) + + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + +type AddMixedConditional = [ +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) + + first: boolean, + null, + third: T extends number ? "a" : "b", +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) + + ...(T extends 0 ? [fourth: "c"] : []) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 34, 25)) + +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +>AddMixedConditionalBoolean : Symbol(AddMixedConditionalBoolean, Decl(partiallyNamedTuples.ts, 39, 2)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) + +type AddMixedConditionalLiteral = AddMixedConditional<0>; +>AddMixedConditionalLiteral : Symbol(AddMixedConditionalLiteral, Decl(partiallyNamedTuples.ts, 41, 63)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) + +type AddMixedConditionalNumberPrimitive = AddMixedConditional; +>AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 42, 57)) +>AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index d98ed8106dfa2..3c04d3c564c03 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -49,15 +49,40 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToMixedTuple<[boolean, number]>; ->AnonymousToMixed : [["0", second: boolean, keyof [boolean, number], fourth: [boolean, number]], ["1", second: number, keyof [boolean, number], fourth: [boolean, number]]] +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +>AnonymousToMixed : [["0", boolean, keyof [boolean, number], [boolean, number]], ["1", number, keyof [boolean, number], [boolean, number]]] -type MixedToMixed = ToMixedTuple<[boolean, second: number]>; ->MixedToMixed : [["0", second: boolean, keyof [boolean, second: number], fourth: [boolean, second: number]], second: ["1", second: number, keyof [boolean, second: number], fourth: [boolean, second: number]]] +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +>MixedToMixed : [["0", boolean, keyof [boolean, second: number], [boolean, second: number]], second: ["1", number, keyof [boolean, second: number], [boolean, second: number]]] -type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; ->NamedToMixed : [first: ["0", second: boolean, keyof [first: boolean, second: number], fourth: [first: boolean, second: number]], second: ["1", second: number, keyof [first: boolean, second: number], fourth: [first: boolean, second: number]]] +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +>NamedToMixed : [first: ["0", boolean, keyof [first: boolean, second: number], [first: boolean, second: number]], second: ["1", number, keyof [first: boolean, second: number], [first: boolean, second: number]]] type MixedSpread = [first: boolean, ...[second: string]]; >MixedSpread : [first: boolean, second: string] +type ConditionalTuple = [ +>ConditionalTuple : [first: boolean, second: string] + + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + +type AddMixedConditional = [ +>AddMixedConditional : [first: boolean, null, third: T extends number ? "a" : "b", ...T extends 0 ? [fourth: "c"] : []] + + first: boolean, + null, + third: T extends number ? "a" : "b", + ...(T extends 0 ? [fourth: "c"] : []) +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +>AddMixedConditionalBoolean : [first: boolean, null, third: "b"] + +type AddMixedConditionalLiteral = AddMixedConditional<0>; +>AddMixedConditionalLiteral : [first: boolean, null, third: "a", fourth: "c"] + +type AddMixedConditionalNumberPrimitive = AddMixedConditional; +>AddMixedConditionalNumberPrimitive : [first: boolean, null, third: "a"] + diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index ecce3c22ce35d..60d926cd162a7 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -21,8 +21,24 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToMixedTuple<[boolean, number]>; -type MixedToMixed = ToMixedTuple<[boolean, second: number]>; -type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; +type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; +type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; + +type ConditionalTuple = [ + first: boolean, + ...(0 extends 0 ? [second: string] : []) +]; + +type AddMixedConditional = [ + first: boolean, + null, + third: T extends number ? "a" : "b", + ...(T extends 0 ? [fourth: "c"] : []) +]; + +type AddMixedConditionalBoolean = AddMixedConditional; +type AddMixedConditionalLiteral = AddMixedConditional<0>; +type AddMixedConditionalNumberPrimitive = AddMixedConditional; From 72ad400525f6ccadc6da811d95b7f0d03cd4e908 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 27 Mar 2023 14:12:01 -0400 Subject: [PATCH 14/16] ToMixedTuple again --- .../reference/partiallyNamedTuples.js | 6 +++--- .../reference/partiallyNamedTuples.symbols | 18 +++++++++--------- .../reference/partiallyNamedTuples.types | 12 ++++++------ .../types/tuple/named/partiallyNamedTuples.ts | 6 +++--- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index b57b6259de30c..f08ac22869c9c 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -22,9 +22,9 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index cca1c59f27269..2e11650484edd 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -79,20 +79,20 @@ type ToMixedTuple = { }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; >AnonymousToMixed : Symbol(AnonymousToMixed, Decl(partiallyNamedTuples.ts, 21, 2)) ->ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; ->MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 60)) ->ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +>MixedToMixed : Symbol(MixedToMixed, Decl(partiallyNamedTuples.ts, 23, 56)) +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; ->NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 64)) ->ToAnonymousTuple : Symbol(ToAnonymousTuple, Decl(partiallyNamedTuples.ts, 9, 72)) +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; +>NamedToMixed : Symbol(NamedToMixed, Decl(partiallyNamedTuples.ts, 24, 60)) +>ToMixedTuple : Symbol(ToMixedTuple, Decl(partiallyNamedTuples.ts, 17, 75)) type MixedSpread = [first: boolean, ...[second: string]]; ->MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 71)) +>MixedSpread : Symbol(MixedSpread, Decl(partiallyNamedTuples.ts, 25, 67)) type ConditionalTuple = [ >ConditionalTuple : Symbol(ConditionalTuple, Decl(partiallyNamedTuples.ts, 27, 57)) diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index 3c04d3c564c03..0c7ec5be1722a 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -49,14 +49,14 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; ->AnonymousToMixed : [["0", boolean, keyof [boolean, number], [boolean, number]], ["1", number, keyof [boolean, number], [boolean, number]]] +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +>AnonymousToMixed : [["0", second: boolean, keyof [boolean, number], fourth: [boolean, number]], ["1", second: number, keyof [boolean, number], fourth: [boolean, number]]] -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; ->MixedToMixed : [["0", boolean, keyof [boolean, second: number], [boolean, second: number]], second: ["1", number, keyof [boolean, second: number], [boolean, second: number]]] +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +>MixedToMixed : [["0", second: boolean, keyof [boolean, second: number], fourth: [boolean, second: number]], second: ["1", second: number, keyof [boolean, second: number], fourth: [boolean, second: number]]] -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; ->NamedToMixed : [first: ["0", boolean, keyof [first: boolean, second: number], [first: boolean, second: number]], second: ["1", number, keyof [first: boolean, second: number], [first: boolean, second: number]]] +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; +>NamedToMixed : [first: ["0", second: boolean, keyof [first: boolean, second: number], fourth: [first: boolean, second: number]], second: ["1", second: number, keyof [first: boolean, second: number], fourth: [first: boolean, second: number]]] type MixedSpread = [first: boolean, ...[second: string]]; >MixedSpread : [first: boolean, second: string] diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index 60d926cd162a7..53aed0dfe31df 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -21,9 +21,9 @@ type ToMixedTuple = { [K in keyof T]: [K, second: T[K], keyof T, fourth: T]; }; -type AnonymousToMixed = ToAnonymousTuple<[boolean, number]>; -type MixedToMixed = ToAnonymousTuple<[boolean, second: number]>; -type NamedToMixed = ToAnonymousTuple<[first: boolean, second: number]>; +type AnonymousToMixed = ToMixedTuple<[boolean, number]>; +type MixedToMixed = ToMixedTuple<[boolean, second: number]>; +type NamedToMixed = ToMixedTuple<[first: boolean, second: number]>; type MixedSpread = [first: boolean, ...[second: string]]; From 1e578a95cc087235545b7e79f8f80d039421bccb Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 28 Mar 2023 15:23:21 -0400 Subject: [PATCH 15/16] Expanded test case for reverse mapping --- .../reference/partiallyNamedTuples.js | 15 +++++++++ .../reference/partiallyNamedTuples.symbols | 33 +++++++++++++++++++ .../reference/partiallyNamedTuples.types | 27 +++++++++++++++ .../types/tuple/named/partiallyNamedTuples.ts | 14 ++++++++ 4 files changed, 89 insertions(+) diff --git a/tests/baselines/reference/partiallyNamedTuples.js b/tests/baselines/reference/partiallyNamedTuples.js index f08ac22869c9c..da47fa65666df 100644 --- a/tests/baselines/reference/partiallyNamedTuples.js +++ b/tests/baselines/reference/partiallyNamedTuples.js @@ -43,6 +43,20 @@ type AddMixedConditional = [ type AddMixedConditionalBoolean = AddMixedConditional; type AddMixedConditionalLiteral = AddMixedConditional<0>; type AddMixedConditionalNumberPrimitive = AddMixedConditional; + +declare function test( + arg: [ + ...{ + [K in keyof T]: { + type: T[K]; + }; + } + ] +): T; + +declare const input: [first: { type: number }, { type: string }]; + +const output = test(input); //// [partiallyNamedTuples.js] @@ -76,3 +90,4 @@ function fb3(a) { args[_i - 1] = arguments[_i]; } } +var output = test(input); diff --git a/tests/baselines/reference/partiallyNamedTuples.symbols b/tests/baselines/reference/partiallyNamedTuples.symbols index 2e11650484edd..4b9b4278b656b 100644 --- a/tests/baselines/reference/partiallyNamedTuples.symbols +++ b/tests/baselines/reference/partiallyNamedTuples.symbols @@ -127,3 +127,36 @@ type AddMixedConditionalNumberPrimitive = AddMixedConditional; >AddMixedConditionalNumberPrimitive : Symbol(AddMixedConditionalNumberPrimitive, Decl(partiallyNamedTuples.ts, 42, 57)) >AddMixedConditional : Symbol(AddMixedConditional, Decl(partiallyNamedTuples.ts, 32, 2)) +declare function test( +>test : Symbol(test, Decl(partiallyNamedTuples.ts, 43, 70)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 45, 22)) + + arg: [ +>arg : Symbol(arg, Decl(partiallyNamedTuples.ts, 45, 52)) + + ...{ + [K in keyof T]: { +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 48, 7)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 45, 22)) + + type: T[K]; +>type : Symbol(type, Decl(partiallyNamedTuples.ts, 48, 23)) +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 45, 22)) +>K : Symbol(K, Decl(partiallyNamedTuples.ts, 48, 7)) + + }; + } + ] +): T; +>T : Symbol(T, Decl(partiallyNamedTuples.ts, 45, 22)) + +declare const input: [first: { type: number }, { type: string }]; +>input : Symbol(input, Decl(partiallyNamedTuples.ts, 55, 13)) +>type : Symbol(type, Decl(partiallyNamedTuples.ts, 55, 30)) +>type : Symbol(type, Decl(partiallyNamedTuples.ts, 55, 48)) + +const output = test(input); +>output : Symbol(output, Decl(partiallyNamedTuples.ts, 57, 5)) +>test : Symbol(test, Decl(partiallyNamedTuples.ts, 43, 70)) +>input : Symbol(input, Decl(partiallyNamedTuples.ts, 55, 13)) + diff --git a/tests/baselines/reference/partiallyNamedTuples.types b/tests/baselines/reference/partiallyNamedTuples.types index 0c7ec5be1722a..8add9f1595e52 100644 --- a/tests/baselines/reference/partiallyNamedTuples.types +++ b/tests/baselines/reference/partiallyNamedTuples.types @@ -86,3 +86,30 @@ type AddMixedConditionalLiteral = AddMixedConditional<0>; type AddMixedConditionalNumberPrimitive = AddMixedConditional; >AddMixedConditionalNumberPrimitive : [first: boolean, null, third: "a"] +declare function test( +>test : (arg: [...{ [K in keyof T]: { type: T[K]; }; }]) => T + + arg: [ +>arg : [...{ [K in keyof T]: { type: T[K]; }; }] + + ...{ + [K in keyof T]: { + type: T[K]; +>type : T[K] + + }; + } + ] +): T; + +declare const input: [first: { type: number }, { type: string }]; +>input : [first: { type: number; }, { type: string; }] +>type : number +>type : string + +const output = test(input); +>output : [first: number, string] +>test(input) : [first: number, string] +>test : (arg: [...{ [K in keyof T]: { type: T[K]; }; }]) => T +>input : [first: { type: number; }, { type: string; }] + diff --git a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts index 53aed0dfe31df..0c6e3752844fd 100644 --- a/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts +++ b/tests/cases/conformance/types/tuple/named/partiallyNamedTuples.ts @@ -42,3 +42,17 @@ type AddMixedConditional = [ type AddMixedConditionalBoolean = AddMixedConditional; type AddMixedConditionalLiteral = AddMixedConditional<0>; type AddMixedConditionalNumberPrimitive = AddMixedConditional; + +declare function test( + arg: [ + ...{ + [K in keyof T]: { + type: T[K]; + }; + } + ] +): T; + +declare const input: [first: { type: number }, { type: string }]; + +const output = test(input); From 88eadcadc591320b62cf1cd5a9869ff66637093e Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 24 Jun 2023 13:25:14 -0400 Subject: [PATCH 16/16] Daniel Rosenwasser: Prettier as a Service Co-authored-by: Daniel Rosenwasser --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 297e883e1950a..166b50ce8b3d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15938,7 +15938,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getTupleTargetType(elementFlags, readonly, map((node as TupleTypeNode).elements, memberIfLabeledElementDeclaration)); } - function memberIfLabeledElementDeclaration(member: Node): NamedTupleMember | ParameterDeclaration | undefined{ + function memberIfLabeledElementDeclaration(member: Node): NamedTupleMember | ParameterDeclaration | undefined { return isNamedTupleMember(member) || isParameter(member) ? member : undefined; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy