betacode

Кортежи (Tuple) в TypeScript

  1. Что такое Tuple?
  2. Tuple vs Array
  3. Methods

1. Что такое Tuple?

В TypeScript, Tuple (Кортеж данных) - это последовательность значений. По сути, Tuple - это массив с дополнительными функциями, вот характеристики of Tuple:
  • Tuple объявляется с определенным количеством элементов и указывает тип для каждого элемента.
  • Начальным значением для Tuple должен быть массив с тем же количеством элементов, что и объявленное число of Tuple.
  • После объявления Tuple и его инициализации у вас будет больше свободы добавлять элементы в Tuple или удалять элементы из Tuple.
Синтаксис:
// Declare a Tuple variable and initialize its value
let myTuple: [dataType1, dataType2, dataTypeN] = [value1, value2, valueN];

// Declare a Tuple variable
let myTuple: [dataType1, dataType2, dataTypeN];
// Initialize its value
myTuple = [value1, value2, valueN];
Например: Мы создаем Tuple с 3 элементами типа [string, string, number]:
tuple_ex1.ts
// string: emp number, string: name, number: salary
let myTuple1: [string, string, number] = ['E01', 'Tom', 1200 ]; // OK

let myTuple2: [string, string, number] = ['E01']; // Error !!
let myTuple3: [string, string, number] = ['E01', 'Tom', 1200, 500]; // Error !!
let myTuple4: [string, string, number] = [100, 200, 300]; // Error !!
let myTuple4: [string, string, number] = ['A', 'B', 'C']; // Error !!
Tuple на самом деле является объектом interface Array. Таким образом, мы можем получить доступ к его элементам через индексы.
tuple_ex2.ts
// string: emp number, string: name, number: salary
let myTuple: [string, string, number] = ['E01', 'Tom', 1200 ];

console.log(myTuple);
console.log(`Type: ${myTuple.constructor.name}`); // Array

console.log(`myTuple[0]: ${myTuple[0]}`); // E01
console.log(`myTuple[1]: ${myTuple[1]}`); // Tom
console.log(`myTuple[2]: ${myTuple[2]}`); // 1200

myTuple[1] = 'Jerry';
console.log(myTuple);
Output:
[ 'E01', 'Tom', 1200 ]
Type: Array
myTuple[0]: E01
myTuple[1]: Tom
myTuple[2]: 1200
[ 'E01', 'Jerry', 1200 ]

2. Tuple vs Array

По сути, Tuple - это массив с дополнительными проверками.
Идеи дизайна of Tuple:
Array
Tuple
Фиксированная длина
No
Yes (*)
Динамическая длина
Yes
No (*)
Содержит множество типов данных
No
Yes
Согласно идеям дизайна of Tuple, вы должны использовать его, когда вам нужен массив с фиксированным размером и определенным типом для каждого элемента. Однако это всего лишь расплывчатое правило. После объявления и инициализации значения для Tuple, вы можете изменить количество элементов of Tuple если хотите.
Например: Используйте метод push() для добавления новых элементов в Tuple (хотя это противоречит дизайнерским идеям of Tuple).
tuple_warning_ex1.ts (**)
// string: staff number, string: name, number: salary
let staff: [string, string, number] = ['E01', 'Tom', 1200 ];

console.log(staff); // [ 'E01', 'Tom', 1200 ]

let newLength = staff.push('New 1', 'New 2');
console.log('New Length: ' + newLength);  // 5
console.log(staff); // [ 'E01', 'Tom', 1200, 'New 1', 'New 2' ]

// The element at index 3 and 4 cannot be accessed directly:
// console.log(staff[3]); // Compile Error !!!
// console.log(staff[4]); // Compile Error !!!
let idx3 = 3;
let idx4 = 4;
// Accessing the elements at index 3 and 4 in this way is OK:
console.log(staff[idx3]); // OK!
console.log(staff[idx4]); // OK!

// Accessing the elements at index 3 and 4 in this way is OK:
for(let idx in staff) {
    console.log(`Element at ${idx} is: ${staff[idx]}`);
}
Output:
[ 'E01', 'Tom', 1200 ]
New Length: 5
[ 'E01', 'Tom', 1200, 'New 1', 'New 2' ]
New 1
New 2
Element at 0 is: E01
Element at 1 is: Tom
Element at 2 is: 1200
Element at 3 is: New 1
Element at 4 is: New 2
Приведенный ниже пример показывает, что иногда полезно нарушать идеи дизайна of Tuple.
tuple_arr_ex1.ts
let employeeInfo: [string, string, number, string] = [
    'E01', // Emp Number
    'Tom', // Emp Name
    1200 , // Salary
    '0901.33333' // Phone Number  
];
employeeInfo.push('0901.44444'); // Second Phone Number
employeeInfo.push('0901.55555'); // Third Phone Number

console.log(employeeInfo);
Output:
[
  'E01',
  'Tom',
  1200,
  '0901.33333',
  '0901.44444',
  '0901.55555'
]

3. Methods

Методы массива (и, конечно, его также можно использовать с Tuple):
Array Interface
interface Array<T> {
  length: number;
  toString(): string;
  toLocaleString(): string;
  pop(): T | undefined;
  push(...items: T[]): number;
  concat(...items: ConcatArray<T>[]): T[];
  concat(...items: (T | ConcatArray<T>)[]): T[];
  join(separator?: string): string;
  reverse(): T[];
  shift(): T | undefined;
  slice(start?: number, end?: number): T[];
  sort(compareFn?: (a: T, b: T) => number): this;
  splice(start: number, deleteCount?: number): T[];
  splice(start: number, deleteCount: number, ...items: T[]): T[];
  unshift(...items: T[]): number;
  indexOf(searchElement: T, fromIndex?: number): number;
  lastIndexOf(searchElement: T, fromIndex?: number): number;
  every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[];
  every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
  some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
  forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
  map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
  filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
  filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
  reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
  reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
  reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
  reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
  reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
  reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
  [n: number]: T;
}
Смотрите примеры использования описанных выше методов в статье о массивах: