FE
3. 객체와 타입 (2)
03-4. 객체의 비구조화 할당문
0. 개요 (구조화)
1) 구조화의 필요성
: 아래와 같이 코드를 구현하면, 작성하기도 번거롭고 기능을 확장하기도 어렵다.
// 구조화의 필요성
let personName = 'Jack';
let personAge = 32;
let companyName = 'Apple Comnay, Inc';
let companyAge = 43;2) 구조화
: 인터페이스나 클래스를 사용해, 관련된 정보를 묶어 새로운 타입으로 표현할 수 있다.
(1) 인터페이스 선언
// 구조화 예시
export interface IPerson{
name: string;
age: number;
}
export interface ICompany{
name: string;
age: number;
}: 이렇게 구조화하면, 코드의 기능 확장이 수월해진다.
(2) 구조화 선언
import { ICompany, IPerson } from "./IPerson_ICompany";
let jack: IPerson = { name: 'Jack', age: 32 },
jane: IPerson = { name: 'Jane', age: 32 };
let apple: ICompany = { name: 'Apple COmputer, Inc', age: 43 },
ms: ICompany = { name: 'Microsoft', age: 44 };
console.log("Person : ", jack, jane);
console.log("Company : ", apple, ms);1. 비구조화란?
: 구조화된 데이터는 어떤 시점에 데이터의 일부만 사용해야 할 때가 있다. 그때 구조화된 데이터를 분해하는 것을 '비구조화(Destructuring)' 라고 한다.
1) 예시
import { IPerson } from "./IPerson_ICompany";
let jack: IPerson = { name: 'Jack', age: 32 };
// 비구조화
let name1 = jack.name, age1 = jack.age;
console.log("destructing1 : ", name1, ", ", age1);2. 비구조화 할당
: 비구조화 할당(destructruing)은 할당을 통해 비구조화를 이뤄내는 것을 의미한다.
배열과 튜플에도 적용할 수 있다.
1) 예시
let { name, age } = jack;
console.log("destructing2 : ", name, ", ", age);비구조화 할당을 객체에 적용하려면 얻고 싶은 속성을 중괄호로 묶는다.
2) 영어 destructuring을 '비구조화'가 아닌, '비구조화 할당'으로 번역한 이유
: 앞의 예시처럼 name, age 변수가 새롭게 만들어지고, name 변수는 jack.name의 값, age 변수는 jack.age의 값을 각각 '초깃값'으로 할당받기 떄문이다.
3. 잔여 연산자
: ESNext Javascript와 Typescript는 점을 연이어 3개를 사용하는 ... 연산자를 제공한다.
이 연산자는 사용되는 위치에 따라 잔여 연산자(Rest operator) 혹은 전개 연산자(spread operator)라고 부른다.
1) 예시
let address: any = {
country: 'Korea',
city: 'Seoul',
address1: "Gangnam-gu",
address2: "Sinsa-dong 123-456",
address3: "789 street, 2 Floor ABC building"
}
const { country, city, ...detail } = address;
console.log(detail);특정 객체에서 특정 속성을 제외한 나머지 속성을 별도의 변수에 저장하고 싶으면, 해당 변수 앞에 잔여 연산자를 붙인다.
4. 전개 연산자
: 점 3개 연산자가 비구조화 할당문이 아닌 곳에서 사용될 때 이를 전개 연산자(spread operator)라고 한다.
1) 예시
// 전개 연산자 예시
let coord = { ...{ x: 0 }, ...{ y: 0 } };
console.log(coord);
let part1 = { name: 'jane' }, part2 = { age: 22 }, part3 = { city: 'Seoul', country: 'Kr' };
let merge = { ...part1, ...part2, ...part3 };
console.log(merge);전개 연산자는 의미 그대로 객체의 속성을 모두 '전개'해 새로운 객체로 만들어 준다.
03-5. 객체의 타입 변환
1. 타입 변환
: 타입이 있는 언어들은 특정 타입의 변숫값을 다른 타입의 값으로 변환해줄 수 있는 기능을 제공하며, 이를 타입 변환(type conversion)이라고 한다.
1) 타입 변환이 필요한 예시
// 타입 변환이 필요한 경우
let person: object = { name: "Jack", age: 32 };
person.name; // object 타입에 Name 속성이 없어서 오류 발생.2) 타입 변환을 진행한 예시
console.log((<{ name: string }>person).name);person 변수를 일시적으로 name 속성이 있는 타입, 즉 {name:string} 타입으로 변환해 person.name 속성값을 얻게 했다.
2. 'type conversion'과 'type casting' 그리고 'type coercion'의 차이
타입 변환으로 번역되는 세 가지 프로그래밍 용어는 type conversion, type casting, type coercion가 있다.
type conversion은 type casting과 type coercion을 모두 포함하는 의미로 사용된다.
type casting은 명시적 타입 변환 (explicit type conversion)을 의미한다. : 명시적이란, 코드에서 직접 표현한다는 의미
type coercion은 암시적 타입 변환 (implicit type conversion)을 의미한다. : 암시적이란, 코드에 굳이 표현하지 않아도 컴파일러나 해석기가 알아서 처리한다는 의미
1) 명시적 타입 변환(type casting)과 암시적 타입 변환(type coercion)의 예시는 다음과 같다.
(1) 명시적 타입 변환 (Type Casting)
개발자가 코드에서 직접 타입 변환을 명시적으로 수행한다.
const num: number = 123;
const str: string = String(num); // number를 string으로 명시적으로 변환
console.log(str); // "123"
const strToNum: number = Number("456"); // string을 number로 명시적으로 변환
console.log(strToNum); // 456(2) 암시적 타입 변환 (Type Coercion)
JavaScript/TypeScript의 엔진이 자동으로 타입을 변환한다.
const result1 = "123" + 456; // string과 number의 덧셈 시 암시적으로 number를 string으로 변환
console.log(result1); // "123456"
const result2 = "100" - 50; // string과 number의 뺄셈 시 암시적으로 string을 number로 변환
console.log(result2); // 50
if ("0") {
console.log("Truthy!"); // "0"은 빈 문자열이 아니기 때문에 암시적으로 true로 평가
}3. 타입 단언
: 타입스크립트는 독특하게 타입 변환이 아닌, 타입 단언(type assertion)이라는 용어를 사용한다.
1) 형태
(<타입>객체)
(객체 as 타입)
: 이들은 모두 ES5 Javascript 구문이 아니다. 따라서 Javascript의 타입 변환 구문과 구분하기 위해 타입 단언이라는 용어를 사용한다.
2) 예시
export default interface INameable {
name : string
}import INameable from "./INameable";
let obj: object = { name: 'Jack' };
// 타입 단언의 두 가지 구문은 서로 형태만 다를 뿐, 내용상으로는 같다.
let name1 = (<INameable>obj).name;
let name2 = (obj as INameable).name;
console.log(name1, name2);