//배열에 타입을 선언하는 두가지 방법
const arr1 : string[] = ['1', '2', '3']
const arr2 : Array<number> = [1, 2, 3]; // 제네릭 표기법
타입스크립트에서 배열의 타입과 빈배열을 선언하면 any 타입으로 추론됩니다.
const arr1 = [1, 2, 3]; //number[]
const arr2 = [1, '2', 3] //(string | number)[]
const arr3 = []; //any
튜플이란 각 요소 자리에 타입이 고정되어 있는 배열을 튜플이라고 합니다. 튜플은 다음과 같습니다.
const tuple : [boolean, string, number] = [true, '1', 1];
tuple[0] = false;
tuple[1] = 5; //err : type 'number' is not assignable to type string
tuple.push('yes!');
console.log(tuple);

배열의 타입추론을 사용하면 문제점이 하나 발생합니다. undefined인 인덱스에 메서드를 붙이면 에러를 알려주지 않는다는 것입니다. 실행은 되지 않지만 정교한 타입의 검사를 원한다면 튜플을 사용해 개선할 수 있습니다.
튜플에서는 push 같은 메서드로 값을 바꾸는 것을 막지 않는다는 것을 명심해야합니다.
//1. 타입추론으로 number[]를 하면서, undefined의 인덱스에도 메서드를 붙일 수 있게 되었습니다. (실행하면 에러가 발생)
const arr = [123, 456, 789 ];
arr[3].toFixed();
//2. 해결법 : 튜플을 사용합니다.
const arr1 : [number, number, number] = [1, 2, 3];
arr1[3].toFixed(); //error
const arr2 : [number, number, number] = [1, 2, 3]; //해결법 2의 문제점은 push, pop, unshift, shift 메서드를 통해 추가하거나 제거하는 것이 가능
arr2.push(4);
//3. 더 정확한 해결법 : readonly 수식어를 붙인 튜플을 사용합니다.
const arr3 : readonly [number, number, number] = [1, 2, 3]
arr3[3].toFixed();
arr3.push(3); //err

// ...타입[] 표기를 통해 특정 타입이 연달아 나올 수 있음
const strNumbool : [string, number, ...boolean[]] = ['hi', 123, false, true, false];
//값에 전개 문법을 사용해도 타입스크립트가 추론해줍니다.
const arr1 = ['h1', true];
const arr = [46, ...arr1]; // const arr :(string | number | number)
구조 분해 할당에서는 나머지 속성 문법을 사용할 수 있습니다. 이 경우에도 타입스크립트가 알아서 추론해줍니다.
const [a,...rest] = ['hi', 1, 23, 456];
console.log(rest); //[1, 23, 456]
타입 뒤에 ? 를 붙이면, 옵셔널 수식어로 해당 자리에 해당 타입의 값이나 undefined 가 들어갈 수 있습니다.
