[하루 30분 러닝 타입스크립트] 배열

✨ 배열 타입

배열과 함수 타입

let createStrings : () => string[]; // 문자열로 구성된 배열을 반환하는 함수
let stringCreators : (() => string)[]; // 함수의 배열

유니언 타입 배열

let stringOrArrayOfNumbers: string | number[]; // 문자열이거나, 값이 숫자인 배열
let arrayOfStringsOrNumbers: (string | number)[]; // 값이 문자열, 숫자인 배열

any 배열의 진화

any타입을 허용하거나, 일반적으로 사용하면 타입 검사 목적을 부분적으로 무효화합니다.

const arr = []; // const arr: any[]

arr.push('') // const arr: string[]

arr[0] = 1; // const arr: (string | number)[]

다차원 배열

2차원 배열 또는 배열의 배열은 두 개의 대괄호를 사용합니다.

let arrayOfArraysOfNumbers: number[][]; // 혹은 (number[])[]
arrayOfArraysOfNumbers = [
    [1,2,3],
    [4,5,6]
]

✨ 배열 멤버

배열의 멤버를 찾아서 해당 배열의 타입 요소를 되돌려 줍니다.

const defenders = ["clarenza", "dina"]

const defender = defenders[0] // const defender: string
const defenders = ["clarenza", "dina", new Date(1782, 6, 3)]

const defender = defenders[0] // const defender: string | Date

❗주의사항. 불안정한 멤버

타입스크립트는 기술적으로 불안정한 부분이 있습니다. 다음 코드는 오류를 표시하지 않습니다.

function withElements(elements: string[]) {
    console.log(elements[90001].length)
}

withElements(["It's", "over"])

✨ 스프레드와 나머지 매개변수

스프레드

const soldiers = ["A", "B", "C"];

const soldierAges = [90, 19, 28];

const conjoined = [...soldiers, ...soldierAges] // const conjoined: (string | number)[]

나머지 매개변수 스프레드

function logWarriors(greeting: string, ...names: string[]){
    for(const name of names){
        console.log(`${greeting}, ${name}`)
    }
}

const warriors = ["A", "B", "C"];
logWarriors("Hello", ...warriors)
// OK

const birthYears = [1999,2000,2001]
logWarriors("Hello", ...birthYears); 
// ERROR Argument of type 'number' is not assignable to parameter of type 'string'.

✨ 튜플

튜플(Tuple)은 고정된 크기의 배열이라 생각하면 됩니다.

let yearAndWarrios: [number, string];
yearAndWarrios = [530, "Tomyris"] // OK

yearAndWarrios = [true, "Tomyris"] 
// ERROR Type 'boolean' is not assignable to type 'number'.

yearAndWarrios = [530] 
/* ERROR Type '[number]' is not assignable to type '[number, string]'.
  Source has 1 element(s) but target requires 2.*/

튜플 할당 가능성

타입스크립트에서 튜플 타입은 가변 길이(variable length)의 배열 타입보다 구체적으로 처리됩니다. 즉 가변 길이의 배열은 튜플 타입에 할당할 수 없습니다.

const pairLoose = [false, 123]; // 가변 가능성이 있는 배열 타입.

const pairTupleLoose: [boolean, number] = pairLoose
/* ERROR Type '(number | boolean)[]' is not assignable to type '[boolean, number]'.
  Target requires 2 element(s) but source may have fewer.*/
const arr: [number, string] = [1, "a"]

const tupleArr1: [number, string] = [arr[0], arr[1]]; // OK
const tupleArr2: [number, string] = [...arr]; // OK
const tupleArr3: [number, string, number] = arr;
/* ERROR Type '[number, string]' is not assignable to type '[number, string, number]'.
  Source has 2 element(s) but target requires 3 */

나머지 매개변수로서의 튜플

function logPair(name: string, value: number){
    console.log(`${name} ${value}`)
}

const arr = ["a", 123]
logPair(...arr)
/* ERROR 
A spread argument must either have a tuple type or be passed to a rest parameter. */

const arr2: [string, number] = ["a", 123]
logPair(...arr2) // OK
function logTrio(name: string, value: [number, boolean]){
    console.log(`${name} ${value[0]} ${value[1]}`)
}

const trios: [string, [number, boolean]][] = [
    ["A", [1,true]],
    ["B", [9,true]],
    ["C", [15,false]],
]

trios.forEach(trio => logTrio(...trio)) // OK

튜플 추론

기본적으로 배열은 가변적인 크기의 배열로 인지하기에, 다음 반환값은 유니언 값으로 추론합니다.

function firstCharAndSize(input: string){
    return [input[0], input.length]
} // (string | number)[] 타입을 반환합니다.

타입스크립트 에서는 두 가지 방법으로 튜플 타입을 명시할 수 있습니다.

1️⃣ 명시적 튜플 타입

function firstCharAndSize(input: string): [string, number] {
    return [input[0], input.length]
} // [string, number] 타입을 반환합니다.

2️⃣ const 어서션

as const 키워드를 사용할 수 있습니다. 이는 읽기 전용(read only) 형식을 취합니다.

const unionArray = [1111, "ABC"];
// const unionArray: (string | number)[]

const readOnlyArray = [1111, "ABC"] as const;
// const readOnlyArray: readonly [1111, "ABC"]
const pairMutable: [number, string] = [1111, "ABC"] as const;
// OK

pairMutable[0] = 1234 // OK
const pairMutable = [1111, "ABC"] as const;

pairMutable[0] = 1234
// ERROR Cannot assign to '0' because it is a read-only property.
function firstCharAndSize(input: string) {
    return [input[0], input.length] as const
} // readonly [string, number] 타입을 반환합니다.