TypeScript 기본기 다지기
Table of Content
1. 원시 타입
새로운 폴더 (metaverse/greeter/src/types)
•
types.ts 생성
//The primitives
const str = "Hello"; // string
const num = 10; // number
const bool = true; // boolean
console.log(str.length); // 5
console.log(str.toUpperCase()); // HELLO
TypeScript
복사
◦
string : 문자열 / “ “ 따옴표로 감싸서 표현
◦
number : 숫자 / 숫자를 표현, Java와 달리 다양한 숫자 타입(예: int, float, double)이 없음
◦
boolean : 논리 / true or false 표현
•
소문자임을 기억하도록 한다. Java 등에서는 대문자로 표기하지만 JavaScript에서의 대문자 String, Number, Boolean은 wrapper 객체로 변환하는 기능이 있는데 사용이 권장되지 않으며 많이 사용되지 않으므로 주의한다.
// ETC : Wrapper object
const wrapperStr = new String(num);
console.log(wrapperStr.length); // 2
console.log(wrapperStr.toUpperCase()); // HELLO
const wrapperNum = new Number("hello");
console.log(wrapperNum.toFixed(2));
const boolNum = 1;
const wrapperBool = new Boolean(boolNum);
console.log(wrapperBool)
TypeScript
복사
2. 배열
배열
•
types.ts
// Array
let arrayOfNumbers1: number[];
arrayOfNumbers1 = [5];
arrayOfNumbers1 = [5, 10, 39];
console.log(arrayOfNumbers1[0]); // 5
console.log(arrayOfNumbers1[1]); // 10
console.log(arrayOfNumbers1[2]); // 39
let arrayOfNumbers2: Array<number>;
arrayOfNumbers2 = [6];
arrayOfNumbers2 = [6, 8, 20];
console.log(arrayOfNumbers2[2]); // 20
TypeScript
복사
•
위 예시 처럼 기본적으로 요소의 타입과 대괄호로 표현해서 선언한다.(주류)
◦
Array와 꺽쇠 괄호 안에 타입을 지정해서 선언 할 수도 있다.
•
하지만 대괄호 안에 타입을 넣는 건 전혀 다른 배열이므로 주의해야 한다.
◦
튜플이란 개념으로 작성한 타입만 들어가도록 인덱스(공간) 1개 허용하는 배열로 초기화되었다는 뜻
// -- tuple
let singleNumberTuple: [number];
singleNumberTuple = [5];
// singleNumberTuple = [5, 10]; // 오류?
// = 초기화 때 메모리(공간, idx)가 이미 지정 됨 -> Java의 배열 초기화와 유사함
// 표기 방식 주의
TypeScript
복사
◦
마치 자바에서 처음 배열의 공간(index) 메모리를 초기화하는 것과 유사한 것이므로 일반적인 배열과 다른 의미이므로 주의
3. 변수와 함수에 대한 타입 표기
변수의 타입 표기
•
처음 작성한 기본 자료형에 타입을 붙여보자.
const str: string = "Hello"; // string
const num: number = 10; // number
const bool: boolean = true; // boolean
TypeScript
복사
•
타입스크립트의 타입 추론 기능을 활용하여 타입을 생략할 수도 있지만 위처럼 명시적 타입 지정으로 코드의 가독성과 안정성을 높이도록 하자
함수(메서드)의 타입 표기
•
함수는 JavaScript에서 데이터를 주고받는 주요 수단, 추후 특정 객체의 멤버인 함수는 메서드라 불리움
•
함수는 입력(Parameter/매개변수)과 출력(Return) 타입을 지정
◦
아래와 같은 함수가 있다.
function greeter(name) {
return "Hello, " + name;
}
TypeScript
복사
◦
해당 함수를 호출하면서 변수를 전달하고자 한다.
▪
name 은 할당된 값이 없기 때문에, 초기화 할 때( ()괄호 안에 넣는 것도 변수 초기화와 같다.) 타입을 지정해 주어야 한다.
▪
아래처럼 타입을 명시적으로 선언해야 한다.
function greeter(name : string) {
return "Hello, " + name;
}
TypeScript
복사
◦
이후 함수를 호출하는데 타입이 맞지 않는 오류를 찾을 수 있음
greeter(44);
TypeScript
복사
◦
파라미터에서는 숫자 타입이 허용되지 않는 것을 볼 수 있다.
•
이제 정상화 시켜서 실행해보자
function hello(name : string) {
return "Hello, " + name;
}
console.log(hello("Tom"));
TypeScript
복사
◦
현재 해당 함수는 “Hello, Tom”이라는 문자열을 반환하고 있다.
▪
아래처럼 타입 자체를 확인해보면 string임을 확인 할 수 있다.
▪
앞으로 많은 파라미터가 추가되고 내부 로직이 추가되게되면 복잡도가 늘어난다.
▪
이런 반환 데이터에 대한 타입도 지정해주면 보다 안정적인 타입 검사를 이용 할 수 있다.
•
특히 추후 특정 객체를 반환하는 것을 통일하기 위해서 사용되므로 반환 타입도 잊지 않고 작성하는 것을 권장한다.
4. 객체
4.1 객체 타입 개념
객체는 속성(Properties)을 가진 타입
•
객체는 말그대로 어떠한 객체, 사물을 떠올리면 된다.
•
사물은 여러 특징, 속성들을 가지고 있으므로 여러 요소들이 포함 될 수 있는 개념으로 접근해야 함
◦
예로 사람은 키, 몸무게, 성별, 나이 등 여러 속성을 가지고 있음
◦
이 속성은 정의하기 나름이며, 수없이 많은 것들을 포함 시킬 수 있음
◦
이런 개념을 그대로 여러 속성을 포함한 하나의 변수로 할당(지정)하는 것
const car = {
color: 'red',
model: 'Sedan',
manufacturer: 'Toyota'
};
const person = {
age: 31,
name: "Tom",
job: "Doctor",
marriage: true
};
TypeScript
복사
◦
지정된 변수에서 도트연산자를 통해 객체의 속성에 각각 접근 할 수 있다.
◦
이 말은 객체는 객체 자체로 객체(object) 타입이면서 각 속성 또한 각각 타입도 있는 계층적 구조를 가지게 된다.
4.2 코드에서의 객체 타입
객체는 사물이 아닌 어떤 개념만으로도 묶일 수도 있다.
•
특별한 의미는 알 수 없는 pt라는 변수에 x, y라는 값을 묶는다고 가정하면
•
이 객체는 지구상의 어떠한 사물은 아니지만, 각 속성을 포함하는 하나의 임의 사물로 판단해야 한다.
◦
따라서 이와 같은 구조를 가질 수 있는 것을 객체라고 확장해서 생각해야 한다.
// 구분자 , or ; 가능
// 표기하지 않는 다면 any라는 타입으로 추론됨 (y 타입 제거 테스트)
function printOutput(pt: { x: number, y: number }) {
console.log("The X value is : " + pt.x);
console.log("The Y value is : " + pt.y);
}
printOutput({x:3, y:5});
// printOutput({x:3, y:"안녕하세요"});
TypeScript
복사
◦
매개변수에서 타입을 지정 하면 함수를 호출 할 때 넘기는 인수에서 인자(매개변수)에서 받을 수 있는 타입이 아닌 경우 오류 발생
◦
매개변수에서 타입을 지정하지 않는 다면 동적으로 타입을 받을 수 있는 any 타입으로 추론되어 사용 됨
4.3 선택적 속성(Optional Propertie)
객체의 속성은 일부 또는 전체 선택적 타입으로 지정 할 수 있다.
•
JavaScript에서는 존재하지 않는 값, 속성에 접근하면 런타임 오류가 발생하지 않지만, undefined 라는 정의되지 않은 값이 할당된다.
•
모든 속성의 값이 없는 경우도 있기 때문에(ex: 회원 가입은 했지만 주소를 아직 등록하지 않은 경우 등 필드가 비어 있을 가능성이 있음) 상황에 따라 유용하게 사용되는 기능이다.
function printName(obj: { first: string, last?: string}) {
if (obj.last !== undefined) {
console.log("Your First name is "+obj.first.toUpperCase())
console.log("Your Last name is "+obj.last.toUpperCase())
} else {
console.log("Your name is "+obj.first.toLowerCase())
}
}
printName({ first: "Bob" }) // last 가 없는데도 IDE 오류가 안나타남
// printName({ first: "Bob", last: "Sponge" })
TypeScript
복사
5. Any
오류 회피용 타입?
•
아래 코드를 IDE에 입력해본다.
let obj: any = { x: 0 };
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;
TypeScript
복사
•
any는 TypeScript의 타입 검사 자체를 진행하지 않는 타입키워드로 생각하면된다.
•
또한 아래 코드들은 모두 정상 작동하게 된다.
•
이는 마치 JavaScript와 유사한 동작을 하게 되면서 TypeScript의 장점을 활용 할 수 없는 의미없는 상태가 되기도 한다.
•
하지만 해당 타입의 존재 이유?
◦
기존 JavaScript 프로젝트 등 코드의 재사용성을 높이기 위함
◦
TS프로젝트에서 방대한 JS 모듈, 라이브러리을 사용하는 편리성을 높이기 위함
•
따라서 해당 타입을 사용하는 것은 간단히 오류를 피하기 위한 임시조치로 사용하면 안되고 의미를 고려하여 사용해야 함
•
tsconfig.json 설정파일에서 해당 관련 옵션을 조정하여 검사 오류를 엄격하게(오류 발생) 적용 할 수도 있다. "noImplicitThis": true,
Related Posts
Search