2023-03-19 TIL (타입스크립트 스터디 6장 배열)

JS2L·2023년 3월 19일
0

6장 배열

6.1 배열 타입

  • 다른 변수와 마찬가지로 배열을 저장하기 위한 변수는 초깃값을 필요로 하지 않음.
  • 변수는 undefined로 시작해서 나중에 배열 값을 받을 수 있다.
const warriors = ['Artemisia', 'Boudica'] // string
warriors.push(true)
// Error: Argument of type 'boolean' is not assignable to parameter of type 'string'.
let arrayOfNumbers: number[]
arrayOfNUmbers = [4, 8, 15, 16, 23, 42]
// Array<number> 같은 구문으로도 작성할 수 있으나 대부분 간단한 number[]를 선호함.

6.1.1 배열과 함수 타입

  • 배열 타입은 함수 타입에 무엇이 있는지를 구별하는 괄호가 필요한 구문 컨테이너의 예이다.
  • 괄호는 Annotation의 어느 부분이 함수 반환 부분이고 어느 부분이 배열 타입 묶음인지 나타내기 위해 사용.
// 타입은 string 배열을 반환하는 함수
let createStrings: () => string[];
// 타입은 각각의 string을 반환하는 함수 배열
let stringCreator: (()=> string)[];

6.1.2 유니언 타입 배열

  • 배열의 각 요소가 여러 선택 타입 중 하나임을 나타낼 때 유니언 타입 사용.
// 타입은 string 또는 number 배열
let stringOrArrayOfNumber: string | number[];
// 타입은 각각 number 또는 string인 요소의 배열 
let arrayOfStringOrNumber: (string|number) [];

6.1.3 any 배열의 진화

  • 초기에 빈 배열로 설정된 변수에서 타입 애너테이션을 포함하지 않으면 타입스크립트는 배열을 any[]로 취급한다.
// 타입: any[]
let values = [];
// 타입:string[]
values.push("somethingString")
// 타입: (number|string)[]
values[0] = 0;

6.1.4 다차원 배열

  • 2차원 배열 또는 배열의 배열은 두개의 [ ]를 갖는다.
  • 3차원은 세개의 [ ], 4차원은 네개의 [ ] 가 있다.
  • 새로운 개념이 아닌 원래 타입을 가지며 끝에 [ ]가 있고 그 뒤에 [ ]를 추가한다.
  • number[][] 타입은 (number[])[]로 나타낼 수 있다.
let arr: number[][]
arr = [
    [1, 2, 3],
    [1, 2, 3],
    [1, 2, 3]
]

6.2 배열 맴버

  • 타입스크립트는 배열의 멤버를 찾아서 해당 배열의 타입 요소를 되돌려주는 인덱스기반 접근 방식을 이해하는 언어다.
const defenders = ["Clarenza", "Dina"]
// 타입은 : string
const defender = defenders[0]
//유니언 타입으로 된 배열의 멤버는 그 자체로 동일한 유니언 타입이다.
//const solOrDate: string | Date
const soldierOrDate = ["Deborah", new Date(1782,6,3)]
// 타입: string | Date
const solOrDate= soldierOrDate[0]

6.2.1 주의사항: 불안정한 맴버

  • 타입스크립트의 타입 시스템은 기술적으로 불안정하다고 알려져 있다.
  • 대부분 올바른 타입을 얻을 수 있지만, 때로는 값 타입에 대한 타입 시스템의 이해가 올바르지 않다.
  • 배열은 타입 시스템에서 불안정한 소스다.
  • 타입스크립트는 모든 배열의 멤버에 대한 접근이 해달 배열의 멤버를 반환한다고 가정하지만 ~
  • 자바스크립트는 배열의 길이보다 큰 인덱스로 배열 요소 접근 시 undefined 를 반환한다.
// 오류를 표시 하지 않는다.
function withElements(element: string[]){
             //element[9001] : string  
  console.log(element[9001].length); // 타입오류 없음
}
withElements(["It's","over"])

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

6.3.1 스프레드

  • spread operator를 사용해 배열을 결합한다.
  • 타입스크립트는 입력된 배열 중 하나의 값이 결과 배열에 포함될 것임을 이해한다.
  • 입력된 배열이 동일한 타입이라면 출력 배열도 동일한 타입이다.
  • 서로 다른 타입의 두 배열을 함께 스프레드해 새 배열을 생성하면 새 배열은 두 개의 타입 중 어느 하나의 요소인 유니언 타입 배열로 이해된다.
// 타입: string[]
const strArr = ["A", "B", "C"]
// 타입: number[]
const numArr = [11,22,33]
// 타입: (string|number)[]
const newArr = [...strArr, ...numArr]

6.3.1 나머지 매개변수

  • 타입스크립트는 나머지 매개변수로 배열을 스프레드하는 자바스크립트 실행을 인식하고 이에 대해 타입 검사를 수행한다.
  • 나머지 매개변수를 위한 인수로 사용되는 배열은 나머지 매개변수와 동일한 배열 타입을 가져야한다.
  • 나머지 매개변수로 string 값만 받는다면 string[] 타입 배열을 스프레드하는 것은 허용되지만, number[]는 허용되지 않는다.
function logWarriors(greeting: string, ...names: string[]) {
    for (const name of names) {
        console.log('${greeting}, ${name}!');
    }
}
const warriors = ['Cathay williams', "Lozen", "Nziga"]
logWarriors("Hello", ...warriors);
const birthYear = [1884, 1840, 1583];
logWarriors("Born in", ... birthYear);
// Error : Argument of type 'number' is not assignable to parameter of type 'string'.

6.4 튜플

  • 자바스크립트 배열은 이론상 어떤 크기라도 될 수 있다.
  • 때로는 튜플이라고 하는 고정된 크기의 배열을 사용하는 것이 유용하다.
  • 튜플은 각 인덱스에 아렬진 특정 타입을 가지며 배열의 모든 가능한 멤버를 갖는 유니언 타입보다 더 구체적이다.
let ageAndName: [number, string] // 인덱스0에 number, 1에 string 값을 갖는 튜플 타입
ageAndName = [33, "koby"] // Ok
ageAndName = [false, 'koby']
// Error : Type 'boolean' is not assignable to type 'number'.
ageAndName =[555]
// Error : Type '[]' is not assignable to type '[number, string]'.
//   Source has 1 element(s) but target requires 2.

6.4.1 튜플 할당 가능성

  • 타입스크립트의 튜플 타입은 가변 길이 배열 타입보다 더 구체적으로 처리된다.
  • 가변 길이의 배열 타입은 튜플 타입에 할당할 수 없다.
  • 튜플은 길이가 다른 튜플은 서로 할당할 수 없다.
  • [boolean, number]가 있는 것을 볼 수 있지만, 타입스크립트는 더 일반적인(boolena | number)[]로 유추한다.
// 타입 : (boolean|number)[]
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 tupleThree: [boolean, number, string] = [false, 1583, 'Nzigna'];
const tupleTwoExact: [boolean, number] = [tupleThree[0], tupleThree[1]]; // Ok
const tupleTwoExtra: [boolean, number] = tupleThree;
//Type '[boolean, number, string]' is not assignable to type '[boolean, number]'.
//  Source has 3 element(s) but target allows only 2.

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

  • 튜플은 구체적인 길이와 요소 타입 정보를 가지는 배열로 간주되므로 함수에 전달할 인수를 저장하는 데 특히 유용하다.
  • 타입스크립트는 spread operator 나머지 매개변수로 전달된 튜플에 정학환 타입 검사를 제공할 수 있다.
function logPair(name: string, value: number){
    console.log('${name} has ${value}')
}
const pairArray = ['Amage', 1];
logPair(...pairArray);
// Error: A spread argument must either have a tuple type or be passed to a rest parameter.
const pairTupleIncorrect: [number, string] = [1, 'Amage'];
logPair(...pairTupleIncorrect);
// Argument of type 'number' is not assignable to parameter of type 'string'. -> 순서가 맞지 않음
const pairTupleCorrect: [string, number] = ['Amage', 1];
logPair(...pairTupleCorrect); // Ok
    • 나머지 매개 변수 튜플을 사용하고 싶다면 여러 번 함수를 호출하는 인수 목록을 배열에 저장해 함께 사용 가능하다.
function logTrio(name: string, value: [number, boolean]){
    console.log(name)
    console.log(value[0], value[1])
}
const trios: [string, [number,boolean]][] = [
    ["A", [1,true]],
    ["B", [2,false]],
    ["C", [3,true]]
]
trios.forEach(trio => logTrio(...trio)) // Ok
trios.forEach(logTrio);
// Error : Argument of type '(name: string, value: [number, boolean]) => void' is not 
//            assignable to parameter of type '(value: [string, [number, boolean]], index: number, array: [string, [number, boolean]][]) => void'.
//            Types of parameters 'name' and 'value' are incompatible.
//            Type '[string, [number, boolean]]' is not assignable to type 'string'.
// [string, [number,boolean]] 전체를 전달하면 매개변수의 타입이 일치하지 않으므로 오류 발생

6.4.2 튜플 추론

  • 타입스크립트로 생성된 배열을 튜플이 아닌 가변 길이의 배열로 취급한다.
  • 배열이 변수의 초깃값 또는 함수에 반환값으로 사용되는 경우, 고정된 튜플이 아니라 유연한 크기의 배열로 가정한다.
// 반환 타입 : (string : number)[]
function firstCharAndSize(input: string) {
    return [input[0], input.length]
}
// firstChar 타입 : string | number
// size 타입 : string | number
const [firstChar, size] = firstCharAndSize("Cookie")

명시적 튜플 타입

  • 함수가 튜플 타입을 반환한다고 선언되고, 배열 리터럴을 반환한다면 튜플로 간주된다.
// 반환 타입 : [string, number]
function firstCharAndSize(input: string) :[string,number] {
    return [input[0], input.length]
}
// firstChar 타입 : string 
// size 타입 : string 
const [firstChar, size] = firstCharAndSize("Cookie")

const 어서션

  • 타입스크립트는 값 뒤에 넣을 수 있는 const Assertion인 as const 연산자를 지원한다.
  • const 어서션 타입스크립트에 타입을 유추할 때 읽기 전용이 가능한 값 형식을 사용하도록 지시
  • 배열 리터럴 뒤 as const가 배치되면 배열이 튜플로 처리되어야 함을 나타낸다.
// 타입: (string | number)[]
const unionArr = [1157, "toto"]
// 타입: readonly [1157, "toto"]
const readonlyArr = [1157, "toto"] as const
  • const Assertion은 튜플로 전환을 넘어서 읽기 전용, 값 수정이 예상 되는 곳에서 사용할 수 없음을 나타낸다.
  • 읽기 전용 튜플은 함수 반환에 편리하다.
//반환 타입: readonly[string, number]
function firstCharAndSizeAsConst(input: string){
    return [input[0], input.length] as const
}
// firstChar : string
// size : number
const [firstChar, size] = firstCharAndSizeAsConst("Cookie")
  • 배열은 가변 배열이 아니라 읽기 전용 튜플로 취급된다.
  • 리터럴은 일반적인 원시 타입과 동등하지 않고 리터럴로 취급된다.
  • 객체의 속성은 읽기 전용으로 간주된다.
const arr = [0, ''];
// arr: (string | number)[]
const arrAsConst = [0, ''] as const;
// arrAsConst: readonly [0, ""]
profile
신입 개발자의 독고다이 개발일지

0개의 댓글