Learning TypeScript 6장

hyena_lee·2023년 3월 16일
0

TypeScript

목록 보기
6/7
post-thumbnail
  • 타입스크립트는 초기 배열에 데이터 타입이 있는지 기억하고, 배열이 해당 데이터 타입에서만 작동하도록 제한한다. (배열이 데이터 타입을 하나로 유지)
  • 아래의 예제를 보면 string 타입 값 추가는 하용되지만 다른 데이터 타입 추가는 혀용되지 않는다.
const bestSongs = ["black swan", "I NEED YOU"];

// ok: "IDOL" 의 타입은 string
bestSongs.push("IDOL");

bestSongs.push(true);
// Error: Argument of type 'boolean' is not assignable to parameter of type 'string'

배열 타입

  • 배열을 저장하기 위한 변수는 초깃값이 필요하지 않는다.
  • 변수는 undefined 로 시작해서 나중에 배열 값을 받을 수 있다.
  • 배열에 대한 타입 애너테이션은 배열의 요소 타입 다음에 []가 와야한다.

let btnAlbums: number[];
btnAlbums = [2, 4, 8, 12, 16, 18, 20, 22];

배열과 함수 타입

  • 골호는 애너테이션의 어느 부분의 함수 반환 부분이고 어는 부분이고 어는 부분이 배열 타입 묶음인지 나타내기 위해 사용한다.
// 타입은 string 배열을 반환하는 함수
let arr1: () => string[];

// 타입은 각각의 string을 반환하는 함수 배열
let arr2: (() => string)[];

유니언 타입 배열

  • 유니언 타입으로 베열 타입을 사용할 때 애너테이션의 어느 부분이 배열의 콘텐츠이고 어느 부분이 유니언 타입 묶은인지를 나태내기 위해 괄호를 사용해야 한다.
  • 유니언 타입에서 괄호 사용은 매우 중요하다.
// 타입은 string 또는  number의 배열
let arr1: string | number[];

// 타입은 각각 number or string의 요소인 배열
let arr2: (string | number)[];
  • string 값과 undefined 값을 모두 가지는 타입의 예
// 타입: (string | undefined)[]
const teamMember = [
	"taetae",
  	"suga",
  	"RM",
  	undefined,
];

any 배열의 진화

  • 초기에 빈 배열로 설정된 변수에서 타입 애너테이션을 포함하지 않으면 타입스크립트는 배열을 arr[]로 취급하고 모든 콘텐츠를 받을 수있다.
  • any 변수가 변경되는 것처럼 any[] 배열이 변경되는 것도 좋아하지 않는다.
  • 타입 애너테이션이 없는 빈 배열은 잠재적으로 잘못된 값 추가를 허용해 타입스크립트의 타입 검사기가 갖는 이점을 부분적으로 무력화 한다.
// 타비 : any[]
let values: [];

// 타입 : string[]
values.push('');

// 타입: (number | string)[]
values[0] = 0;

다차원 배열

-2차원 배열 또는 배열의 배열은 두 개의 를 갖는다.

let lifeGoesOn: number[][];

lifeGoesOn = [
	[1,2,3],
  	[2,4,6],
  	[3,6,9],
];

배열 멤버

  • 배열의 멤버를 찾아서 해당 배열의 타입 요소를 되돌려주는 전형적인 인덱스 기반 접근방식이다.
const bestSongs = ["Run", "DNA"];

// 타입: string
const bestSong = bestSongs[0];
  • 유니언 타입으로 된 배열의 멤버는 그 자체로 동일한 유니언 타입이다.
const btsMembers = ["V", new Date(1995, 12, 30)];

// 타입 : string | Date
const btsMember = btsMembers[0];

주의사항: 불안정한 멤버

  • 타입스크립는 모든 배열의 멤버에 대한 접근이 해당 배열의 멤버를 반환한다고 가정하지만, 자바스크립트에서 조차도 배열의 길이보다 큰 인덱스로 배열 요소에 접근하면 undefined를 제공합니다.
function withMembers(members: string[]) {
  	console.log(members[1995].length);  // 타입 오류 없음
}
withMembers(["For", "youth"]);
  

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

스프레드

  • ...스프레드 연산자를 사용해 배열을 결합합니다.
  • 서로 다른 타입의 두 배열을 함께 스프레드해 새 배열을 생성하면 새 배열은 두 개의 원래 타입 중 어느 하나의 요소인 유니언 타입 배열로 이해된다.
// 타입: string[]
const btsMember = ["V", "JK", "Jimin"];

// 타입: number[]
const btsAge : [29, 27, 29];

// 타입 : (string | number)[]
const hybe = [...bts, ...btsAge];

나머지 매개변수 스프레드

  • 타임스크립트는 나머지 매개변수로 배열을 스프레드하는 자바스크립트 실행을 인식하고 이에 대해 검사를 수행하낟.
  • 나머지 매개변수를 위한 인수로 사용되는 배열은 나머지 매개변수와 동일한 배열 타입을 가져야 한다.
function hybe(greeting: string, ...names: string[]) {
  for(const name of names) {
    console.log('${greeting}, ${name}!');
  }
}

const member = ["V", "RM", "JK"];
member("Hello", ...member);
const bithYears = [1995, 1994, 1997];
member("Born in", ...birthYears);
// Error: Argument of type 'number'  is not assignable to parameter of type 'string'.

튜플

  • 고정된 크기의 배열을 튜플이라고한다.
  • 배열의 모든 가능한 멤버를 갖는 유니언 타입보다 더 구체적읻.
  • 튜플 타입을 선언하는 구문은 배열 리터럴처럼 보이지만 요소의 값 대신 타입을 적는다
let yearAndbts: [number, string];

yearAndbts = [7, "BangTan"];

yeearAndbts = [false, "Bangtan"];
// Error: Type 'boolean' is not assignable to type 'number'

yearAndbts = [7];
//Error: Type '[number]' is not assignable to type '[number, string]'.
// source has 1 elements(s) but target requires2 
  • 단일 조건을 기반으로 두 개의 변수에 초깃값을 설정하는 것처럼 한 번에 여러 값을 할당하기 위해 튜플과 배열구조 분해 할당을 함께 자주 사용
// year 타입: number
// bts 타입 :  string
let [year, bts] = Math.random() > 0.5
	? [7, "BangTan"]
	: [5, "NewJeans"];

튜플 할당 가능성

  • 타입스크립트에서 튜플 타입은 가변길이이 배열 타입보다 더 구체적으로 처리된다.
  • 가변길의 배열타입은 튜플 타입에 할당 할 수 없다.
// 타입: (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 elements(s) but source may have fewer.
  • pairLoose 가 [boolean, number] 자체로 선언된 경우 pairTupleLoose에 대한 값 할당이 허용되었을 것이다.
  • 타입스크립트는 튜플 타입의 튜플에 얼마나 많은 멤버가 있는지 알고 있기 때문에 길이가 다른 튜플은 서로 할당 할수 없다.

const bts = [boolean, number, string] = [false, 2013, "BangTan"];

const btsNewJeans: [boolean, number] = [bts[0], bts[1]];

const btsBlakPink: [boolean, number] = bts;
// Error: Type '[boolean, number, string]' is not assignable to type '[boolean, number]'
// source has 3 elements(s) but target allows only 2

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

  • 튜플은 구체적인 길이와 요소타입정보를 가지는 배열로 간주되므로 함수에 전달할 인수를 저장하는데 특히 유용하다.
function newJeans(name: string, value: number) {
  console.log('${name} has ${value}');
}
const hybeArray = ["V", 1];
newJeans(..hybeArray);
// Error: A spread argument must either have a tuple type or be passed to a rest paramter.

const hybeTomorrow: [number, string] = [5, "TXT"];
newJeans(...hybeTomorrow);
// Error: Argument of type 'number is not assignable to parameter of type 'string'

const hybeSpring: [string, number] = ["flower", 4];
newJeans(hybeSpring);  // ok
  • 나머지 매개변수 튜플을 사용하고 싶다면 여러번 함수를 호출하는 인수 목록을 배열에 저장해 함께 사용할 수 있다.
  • 가변 길이의 배열 타입은 튜플 타입에 할당할 수 없다.
function logPair(name: string, value: [number, boolean]) {
  console.log('${name} has ${value[0]} (${value[1]}');
}

const trios: [string, [number, boolean]][] = [
	["V", [1, true]],
  	["Rm", [2, false]],
  	["JK", [3, false]]
];

trios.forEach(trio => logtrio(..trio));  ///ok

trios.forEach(logpair);
//Error: Argument of type '(name: string, value: [number, boolean]) => vild
  • 여러번 함수를 호출하는 인수 목록을 배열에 저정해 함께 사용할 수있다.
  • trios는 튜플 배열이고, 각 튜플은 두 번째 멤버로 또 튜플을 가진다.
  • trios.forEach(trio => logTrio(...trio))는 각 ...trio가 logTrio의 매개변수 타입과 일치하므로 안전하다.
  • trio.forEach(logTrio)는 첫번째 매개변수로 타입이 string인 [string, [number, boolean]] 전체를 전달하려고 시도하기 때문에 할당 할 수없다.

튜플 추론

-타입스크립트 생성된 배열을 튜플이 아닌 가변 길이의 배열로 취급한다.

  • 배열이 변수의 초깃값 또는 함수에 대한 반환값으로 사용되고, 고정된 크기의 튜플이 아니라 유연한 크기의 배열로 가정한다.
//반환 타입 : (string | number)[]
function hybe(input: string) {
  return [input[0], input,.length];
}


// hybe 타입: string | number
// size 타입: string | number
const [hybeNew, size] = hybe("bts");

=> [string, number] 아니라 (string | number)[]를 반환하는 것으로 유추 된다.

명시적 튜플 타입

  • 튜플 타입도 타입 애너테이션에 사용 할 수 있다.
  • 함수가 튜플 타입을 반환한다고 선언되고, 배열 리터럴을 반환한다면 해당 배열 리터럴을 일반적인 가변길이의 배열 대신 튜플로 간주된다.
//반환 타입 : [string, number]
function hybeToSizebts(input: string): [string,number] {
  return [inpit[0], input.length];
}

// hybeSize 타입: string
// size 타입 : number
const [hybeTo, size] = hybeNewJeans("bts");

conset 어서션

  • 명시적 타입 애너테이션에 튜플 타입을 입력하는 작얿은 명시적 타입 애너테이션을 입력할 때와 동일한 이유로 고통스러울 수 잇다
  • 코드 변경에 따라 작성 및 수정이 필요한 구문을 추가해야한다.
  • 타입스크립트는 값 뒤에 넣을 수 있는 const 어서션인, as const 연산자를 제공
  • 타입을 유추할 때 읽기 전용이 가능한 값 형식을 사용도록 지시함.
  • as cosnt 가 배치되면 배열이 튜플로 처리되어야 한다.
// 타입 : (string |number) 
const taetae = [1995, "V"];

// 타입 : readonly [1995, "V"]
const readonlyTuple = [1995, "V"] as const;
  • const 어서션은 유연한 크기의 배열을 고정된 크기의 튜플로 전환하는 것을 넘어서, 해당 튜플이 읽기 전용이고 값 수정이 예상되는 곳에서 사용할 수없음을 나타낸다.
const taetae: [number, string] = [1995, "v"];
taeatae[0] = 12431; // ok

const taetaeNew: [number, string] = [1995, "v"] as const;

//Error: The type 'readonly [1995, "V"] is "readonly'
// and cannot be assigned to the mutable type '[number, string]'.

const taetaeConst = [1995, "v"] as const;
taetaeConst[0] = 1230;

// Error : Cannot asign to '0' because it is a read-only property.

알게된 점)
readonly 속성은 불리언 속성으로서 해당 속성을 명시하지 않으면 속성값이 자동으로 false 값을 가지게 되며, 명시되면 자동으로 true 값을 가지게 된다.

  • 실제로 읽기 전용 튜플은 함수변환에 편리하다.
  • 함수로부터 반환된 값은 보통즉시 구조화되지 않으므로 읽기 전용인 튜플은 함수를 사용하는데 방해가 되지 않는다.
// 반환 타입: readonly [string, number]
function hybeToSizeConst(input: string) {
  return [input[0], input.length] as const;
}

// hybeTo 타입 : string
// size 타입 : number
const [hybeTo, size] = hybetoSizeConst("V");

[Reference]
1. Learning typeScript(조시 골드버그/고승원/한빛미디어_2023)

profile
실수를 두려워 말고 계속 도전 하는 개발자의 여정!

0개의 댓글