Skip to content

Commit

Permalink
Fix tuple name homogeneity check
Browse files Browse the repository at this point in the history
  • Loading branch information
weswigham committed Aug 18, 2020
1 parent 6fea7ff commit e1f4f9c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 27 deletions.
7 changes: 2 additions & 5 deletions src/compiler/checker.ts
Expand Up @@ -31080,13 +31080,10 @@ namespace ts {
function checkTupleType(node: TupleTypeNode) {
const elementTypes = node.elements;
let seenOptionalElement = false;
let seenNamedElement = false;
const hasNamedElement = some(elementTypes, isNamedTupleMember);
for (let i = 0; i < elementTypes.length; i++) {
const e = elementTypes[i];
if (e.kind === SyntaxKind.NamedTupleMember) {
seenNamedElement = true;
}
else if (seenNamedElement) {
if (e.kind !== SyntaxKind.NamedTupleMember && hasNamedElement) {
grammarErrorOnNode(e, Diagnostics.Tuple_members_must_all_have_names_or_all_not_have_names);
break;
}
Expand Down
34 changes: 23 additions & 11 deletions tests/baselines/reference/namedTupleMembersErrors.errors.txt
@@ -1,28 +1,40 @@
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(3,32): error TS5084: Tuple members must all have names or all not have names.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(5,32): error TS5084: Tuple members must all have names or all not have names.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(7,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(9,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(11,49): 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(11,52): error TS8020: JSDoc types can only be used inside documentation comments.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(13,39): error TS5085: A tuple member cannot be both optional and rest.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(15,44): error TS2574: A rest element type must be an array type.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(17,13): error TS2456: Type alias 'RecusiveRestUnlabeled' circularly references itself.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(18,13): error TS2456: Type alias 'RecusiveRest' circularly references itself.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(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.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(14,52): error TS8020: JSDoc types can only be used inside documentation comments.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(16,39): error TS5085: A tuple member cannot be both optional and rest.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(18,44): error TS2574: A rest element type must be an array type.
tests/cases/conformance/types/tuple/named/namedTupleMembersErrors.ts(20,13): error TS2456: Type alias 'RecusiveRestUnlabeled' circularly references itself.
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 (11 errors) ====
==== 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.

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 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 Opt = [element: string?]; // question mark on element disallowed
~~~~~~~
Expand Down
6 changes: 6 additions & 0 deletions tests/baselines/reference/namedTupleMembersErrors.js
@@ -1,9 +1,12 @@
//// [namedTupleMembersErrors.ts]
export type Segment1 = [length: number, number]; // partially named, disallowed
export type Segment2 = [number, size: number]; // partially named, disallowed

export type List = [item: any, ...any]; // partially named, disallowed
export type List2 = [any, ...remainder: any]; // partially named, disallowed

export type Pair = [item: any, any?]; // partially named, disallowed
export type Pair2 = [any, last?: any]; // partially named, disallowed

export type Opt = [element: string?]; // question mark on element disallowed

Expand All @@ -26,8 +29,11 @@ exports.__esModule = true;

//// [namedTupleMembersErrors.d.ts]
export declare type Segment1 = [length: number, number];
export declare type Segment2 = [number, size: number];
export declare type List = [item: any, ...any];
export declare type List2 = [any, ...remainder: any];
export declare type Pair = [item: any, any?];
export declare type Pair2 = [any, last?: any];
export declare type Opt = [element: string?];
export declare type Trailing = [first: string, rest: ...string[]];
export declare type OptTrailing = [first: string, rest: ...?string[]];
Expand Down
31 changes: 20 additions & 11 deletions tests/baselines/reference/namedTupleMembersErrors.symbols
Expand Up @@ -2,32 +2,41 @@
export type Segment1 = [length: number, number]; // partially named, disallowed
>Segment1 : Symbol(Segment1, Decl(namedTupleMembersErrors.ts, 0, 0))

export type Segment2 = [number, size: number]; // partially named, disallowed
>Segment2 : Symbol(Segment2, Decl(namedTupleMembersErrors.ts, 0, 48))

export type List = [item: any, ...any]; // partially named, disallowed
>List : Symbol(List, Decl(namedTupleMembersErrors.ts, 0, 48))
>List : Symbol(List, Decl(namedTupleMembersErrors.ts, 1, 46))

export type List2 = [any, ...remainder: any]; // partially named, disallowed
>List2 : Symbol(List2, Decl(namedTupleMembersErrors.ts, 3, 39))

export type Pair = [item: any, any?]; // partially named, disallowed
>Pair : Symbol(Pair, Decl(namedTupleMembersErrors.ts, 2, 39))
>Pair : Symbol(Pair, Decl(namedTupleMembersErrors.ts, 4, 45))

export type Pair2 = [any, last?: any]; // partially named, disallowed
>Pair2 : Symbol(Pair2, Decl(namedTupleMembersErrors.ts, 6, 37))

export type Opt = [element: string?]; // question mark on element disallowed
>Opt : Symbol(Opt, Decl(namedTupleMembersErrors.ts, 4, 37))
>Opt : Symbol(Opt, Decl(namedTupleMembersErrors.ts, 7, 38))

export type Trailing = [first: string, rest: ...string[]]; // dots on element disallowed
>Trailing : Symbol(Trailing, Decl(namedTupleMembersErrors.ts, 6, 37))
>Trailing : Symbol(Trailing, Decl(namedTupleMembersErrors.ts, 9, 37))

export type OptTrailing = [first: string, rest: ...string[]?]; // dots+question on element disallowed
>OptTrailing : Symbol(OptTrailing, Decl(namedTupleMembersErrors.ts, 8, 58))
>OptTrailing : Symbol(OptTrailing, Decl(namedTupleMembersErrors.ts, 11, 58))

export type OptRest = [first: string, ...rest?: string[]]; // rest+optional disallowed
>OptRest : Symbol(OptRest, Decl(namedTupleMembersErrors.ts, 10, 62))
>OptRest : Symbol(OptRest, Decl(namedTupleMembersErrors.ts, 13, 62))

export type NonArrayRest = [first: string, ...rest: number]; // non-arraylike rest, disallowed
>NonArrayRest : Symbol(NonArrayRest, Decl(namedTupleMembersErrors.ts, 12, 58))
>NonArrayRest : Symbol(NonArrayRest, Decl(namedTupleMembersErrors.ts, 15, 58))

export type RecusiveRestUnlabeled = [string, ...RecusiveRestUnlabeled];
>RecusiveRestUnlabeled : Symbol(RecusiveRestUnlabeled, Decl(namedTupleMembersErrors.ts, 14, 60))
>RecusiveRestUnlabeled : Symbol(RecusiveRestUnlabeled, Decl(namedTupleMembersErrors.ts, 14, 60))
>RecusiveRestUnlabeled : Symbol(RecusiveRestUnlabeled, Decl(namedTupleMembersErrors.ts, 17, 60))
>RecusiveRestUnlabeled : Symbol(RecusiveRestUnlabeled, Decl(namedTupleMembersErrors.ts, 17, 60))

export type RecusiveRest = [first: string, ...rest: RecusiveRest]; // marked as incorrect, same as above
>RecusiveRest : Symbol(RecusiveRest, Decl(namedTupleMembersErrors.ts, 16, 71))
>RecusiveRest : Symbol(RecusiveRest, Decl(namedTupleMembersErrors.ts, 16, 71))
>RecusiveRest : Symbol(RecusiveRest, Decl(namedTupleMembersErrors.ts, 19, 71))
>RecusiveRest : Symbol(RecusiveRest, Decl(namedTupleMembersErrors.ts, 19, 71))

9 changes: 9 additions & 0 deletions tests/baselines/reference/namedTupleMembersErrors.types
Expand Up @@ -2,12 +2,21 @@
export type Segment1 = [length: number, number]; // partially named, disallowed
>Segment1 : Segment1

export type Segment2 = [number, size: number]; // partially named, disallowed
>Segment2 : Segment2

export type List = [item: any, ...any]; // partially named, disallowed
>List : [any, ...any[]]

export type List2 = [any, ...remainder: any]; // partially named, disallowed
>List2 : [any, ...any[]]

export type Pair = [item: any, any?]; // partially named, disallowed
>Pair : Pair

export type Pair2 = [any, last?: any]; // partially named, disallowed
>Pair2 : Pair2

export type Opt = [element: string?]; // question mark on element disallowed
>Opt : Opt

Expand Down
@@ -1,10 +1,13 @@
// @declaration: true

export type Segment1 = [length: number, number]; // partially named, disallowed
export type Segment2 = [number, size: number]; // partially named, disallowed

export type List = [item: any, ...any]; // partially named, disallowed
export type List2 = [any, ...remainder: any]; // partially named, disallowed

export type Pair = [item: any, any?]; // partially named, disallowed
export type Pair2 = [any, last?: any]; // partially named, disallowed

export type Opt = [element: string?]; // question mark on element disallowed

Expand Down

0 comments on commit e1f4f9c

Please sign in to comment.