- Published on
TypeScript 기본 & 기본 타입
TypeScript 사용하는 이유
타입 스크립트란?
- 타입스크립트는 자바스크립트의 슈퍼셋으로서, 코드를 실행하여 타입스크립트 코드를 자바스크립트로 컴파일하는
컴파일러- 단독으로 실행할 수 없으며, 컴파일된 자바스크립트를 output 함
- 자바스크립트를 기반으로 새로운 기능과 장점을 추가하는 언어
- 나은 구문과 작업을 보다 손쉽게 수행할 수 있게 해주는 방법 제공
- 코드의 에러를
컴파일 단계에서 캐치할 수 있음
- 브라우저와 같은 자바스크립트 환경에서 실행할 수 없음
TypeScript 기본 & 기본 타입
타입 이해하기
타입 사용하기
| number | 1, 5.3, -10 | 모든 숫자, 정수와 실수에는 차이가 없음 |
|---|---|---|
| string | 'Hi’, “Hi”, `HI` | 간단한 텍스트 |
| boolean | true, false | 참 또는 거짓이라는 두 값 |
문제 인식
Javascript
function add(n1, n2) {
return n1 + n2
}
const number1 = '5'
const number2 = 2.8
const result = add(number1, number2)
console.log(result) // 52.8
- Javascript는 수학적 방식으로 처리하는 게 아닌 문자열로 처리함
- 값이 할당되기 전에는 무슨 데이터 타입인지 알지 못함
- 할당 된 후에도 우리가 인지하는 수학적 계산에 의한 결과 값을 얻지 못함
- 복잡도가 큰 로직에서 에러를 찾아내기 어려울 수 있음
Typescript
function add(n1: number, n2: number) {
return n1 + n2
}
const number1 = '5'
const number2 = 2.8
const result = add(number1, number2)
console.log(result) // 52.8
app.ts:8:20 - error TS2345: Argument of type '"5"' is not assignable to parameter of type 'number'.
# 문자열 5라는 유형의 인수는 '숫자형' 타입의 매개변수에 할당할 수 없습니다.
8 const result = add(number1, number2);
함수에 있는 타입 배정을 매개변수에 추가하여,
타입 추론을 할 수 있게 수정두 매개변수가
숫자형 타입이어야 하며, 어느 것이 기본값이어야 하는지 상관없다고 입력할 수 있음전달하고자 하는 함수의 매개 변수
타입이 맞지 않을 경우, 에러를 발생함컴파일 하는 동안에만 에러가 고정되어 나타남
브라우저에는
내장 타입스크립트 지원이 없으므로, 런타임에서 자바스크립트가 다른 식으로 작동하지 않도록 변경하지 않음
TypeScript 타입 vs Javascript 타입
Javascript(typeof 연산자 사용)
function add(n1, n2) {
if (typeof n1 !== 'number' || typeof n2 !== 'number') {
throw new Error('Incorrect input!!!')
}
return n1 + n2
}
const number1 = '5'
const number2 = 2.8
const result = add(number1, number2)
console.log(result)
- typeof 연산자를 사용하여 타입이
number와 같은 지 런타임 검사를 실행할 수 있음 - 자바스크립트는 숫자형, 문자열, 불리언과 같은 타입들을 알고 있지만 런타임 단계전에 알 수 없으므로 타입스크립트에 비해 먼저 버그를 잡아낼 수 없음
Typescript
function add(n1: number, n2: number) {
return n1 + n2
}
const number1 = 5
const number2 = 2.8
const result = add(number1, number2)
console.log(result)
- 타입스크립트는 자바스크립트에 비해
훨씬 많은 타입을 알고 있으므로, 자바스크립트의 런타임 검사보다 더 유연하고 강력하게타입 검사를 할 수 있음 - 하지만, 자바스크립트 엔진에 내장되어 있지 않으므로 타입스크립트로
개발하는 도중에만타입 추론 기능을 사용할 수 있음
타입스크립트의 주요 원시 타입은 모두 소문자임
숫자 문자열 및 불리언 작업하기
function add(n1: number, n2: number, showResult: boolean, phrase: string) {
const result = n1 + n2
if (showResult) {
console.log(phrase + result)
} else {
return n1 + n2
}
}
const number1 = 5
const number2 = 2.8
const printResult = true
const resultPhrase = 'Result is '
const result = add(number1, number2, printResult, resultPhrase)
console.log(result)
- 자바스크립트와 타입스크립트는 정수와 실수를 구분하지 않음
console.log(phrase + result);- n1, n2 매개변수 값은
문자열과 같이 연산되는 경우에 자바스크립트에서는문자열로 인식하므로, if 조건절을 만나기 전에수학적 계산을 변수에 할당하여 값을 저장하고 문자열과 연산해주는 것이 안전함
- n1, n2 매개변수 값은
타입 할당 및 타입 추론하기
특정 변수나 상수에 어떤 타입을 사용했는지 타입스크립는
타입 추론(type interface)를 통해 내장 기능을 활용함변수를 선언하여 값을 할당할 때, 지정한 타입값을 직접 지정하는 방식보다 어떤 값을 저장할 지 먼저 타입스크립트에 알려주는 편이 좋음
let number1: number number1 = 5 const number2 = 2.8 const printResult = true let resultPhrase = 'Result is '타입을 잘못 사용하고 있는지 확인하고 에러를 통해 알려주는 핵심 작업을 수행함
핵심 타입 & 개념
객체 형태
| object | {age:30} | 자바스크립트 객체, 더 특정한 타입의 객체도 가능함 |
|---|
const person: {
name: string
age: number
} = {
// const person = {
name: 'Maximilian',
age: 30,
}
console.log(person.name)
- 키 타입을 명시하여, 타입스크립트가 이 코드를
추론할 수 있도록 해야 함 타입과타입 배정은 자바스크립트가 아닌타입스크립트에만 해당하므로, 컴파일이 완료된 자바스크립트에는 타입과 관련된 코드는 생략됨- 타입스크립트는 작업 중인 객체를 이해할 수 있도록 해주는 객체 타입 표현 방식일 뿐 실제로 자바스크립트의 객체를 생성하지는 않음
배열 타입
| Array | [1, 2, 3] | 어떤 자바스크립트 배열이든 지원하며 배열의 타입을 유연하게, 제한적으로도 지정할 수 있음 |
|---|
// const person: {
// name: string;
// age: number;
// } = {
const person = {
name: 'Maximilian',
age: 30,
hobbies: ['Sports', 'Cooking'],
}
let favoriteActivities: string[]
favoriteActivities = ['Sports']
console.log(person.name)
for (const hobby of person.hobbies) {
console.log(hobby.toUpperCase())
}
- 타입스크립트는
hobbies가 문자열의 배열 타입으로 이해하므로,person.hobbies를 입력하면hobbies를 문자열의 배열이라고 인식함- 문자열로 지정되는 hobby를 사용하여 어떤 작업이든 가능하게 해줌
- 가령 map과 같이 문자열에서 사용하지 못하는 메서드를 인식하여, Error를 발생시킴
튜플 작업하기
| Tuple | [1,2] | 타입스크립트에서 추가된 길이가 고정된 배열, 타입도 고정할 수 있음 |
|---|
const person: {
name: string
age: number
hobbies: string[]
role: [number, string]
} = {
name: 'Maximilian',
age: 30,
hobbies: ['Sports', 'Cooking'],
role: [2, 'author'],
}
// person.role.push('admin');
// person.role[1] = 10; // Error!
- 배열의
길이와,타입을 고정- 위에서 정의한 구조와
정확히 일치하게 값을 할당해야 함
- 위에서 정의한 구조와
- push 메서드는 타입스크립트에서 예외적으로 튜플에서 허용되지만, 잘못된 값을 할당하지는 않음
튜플을 사용하여작업 중인 데이터 타입과예상되는 데이터 타입을 보다 명확하게파악할 수 있음
열거형으로 작업하기
| Enum | enum { NEW, OLD } | 자바스크립트에는 존재하지 않는 타입, 0부터 시작하는 숫자로 전역적인 상수 식별자 개념으로 쓰임 |
|---|
// const ADMIN = 0;
// const READ_ONLY = 1;
// const AUTHOR = 2;
enum Role { ADMIN, READ_ONLY, AUTHOR };
const person {
name: 'Maximilian',
age: 30,
hobbies: ['Sports', 'Cooking'],
role: Role.ADMIN
};
if(person.role === Role.AUTHOR) {
console.log('is auth');
}
Enum키워드를 사용해 라벨을 0부터 시작하는 숫자로 할당하게 해줌- 시작 숫자는 =(등호)를 통해 초기화하면 값을 할당한 식별자 다음의 식별자들은 증가됨
- 백그라운드에서 매핑된 값이 있는 식별자가 필요할 때 훌륭한 선택지가 될 수 있음
Any 타입
| Any | * | 모든 종류의 값, 특정되지 않은 타입 |
|---|
- 아주 유연하고 훌륭한 타입 같지만, 타입스크립트가 주는 모든 장점을 any가 상쇄시키므로 가급적 쓰지 않는 것이 좋음
- 런타임 검사를 수행하는 경우, 특정 값에 수행하고자 하는 작업의 범위를 좁히기 위해서 any를 사용하고 그 외의 경우 사용하지 않는 것이 좋음
- any 타입을 사용하는 모든 위치에서는 타입스크립트 컴파일러가 작동을 하지 않게 되므로 any 속성 또는 any 변수가 어떤 값도 저장하지 않아 컴파일러가 검사할 부분이 없어짐
조합(Union) 타입
function combine(input1: number | string, input2: number | string) {
let result
if (typeof input1 === 'number' && typeof input2 === 'number') {
result = input1 + input2
} else {
result = input1.toString() + input2.toString()
}
return result
}
const combinedAges = combine(30, 26)
console.log(combinedAges)
const combinedNames = combine('Max', 'Anna')
console.log(combinedNames)
- 파이브 기호(
|)를 통해 두 가지 이상의 타입을 필요한 만큼 사용함 - 타입스크립트는 유니언 타입만 이해할뿐 유니언 타입 내에 무엇이 있는지는 분석하지 못함
- 타입스크립트는 그저 여러 타입이 입력됐으니, 더하기 연산자를 사용할 수 없는 타입도 있을 것이라고 이해함
유니언 타입을 사용하여 작업할 때에는 추가적인런타임 타입 검사를 통해 코드에 적용한 매개변수를 보다 유연하게 처리할 수 있음- 타입에 따라 함수 내에 다른 로직을 적용할 수 있음
리터럴 타입
function combine(
input1: number | string,
input2: number | string,
resultConversion: 'as-number' | 'as-text'
) {
let result
if (
(typeof input1 === 'number' && typeof input2 === 'number') ||
resultConversion === 'as-number'
) {
result = input1 + input2
} else {
result = input1.toString() + input2.toString()
}
return result
}
const combinedAges = combine(30, 26, 'as-number')
console.log(combinedAges) // 56
const combinedStringAges = combine('30', '26', 'as-number')
console.log(combinedStringAges) // 56
const combinedNames = combine('Max', 'Anna', 'asText')
console.log(combinedNames) // MaxAnna
- 스트링이나 숫자 등과 같은 핵심 타입과 마찬가지로 특정 문자열을 특정하여 값을 허용할 수 있음
resultConversion은‘as-number’과‘as-text’두 값중 하나여야 하고 다른 값은 허용하지 않으며 해당 값들을 보장받을 수 있음- 해당하지 않는 값을 대입하면 컴파일 에러를 일으킴
- 유니언 타입을 결합하는 데 사용
타입 알리어스 / 사용자 정의 타입
type Combinable = number | string
type ConversionDescriptor = 'as-number' | 'as-text'
function combine(input1: Combinable, input2: Combinable, resultConversion: ConversionDescriptor) {
let result
if (
(typeof input1 === 'number' && typeof input2 === 'number') ||
resultConversion === 'as-number'
) {
result = input1 + input2
} else {
result = input1.toString() + input2.toString()
}
return result
}
항상 유니언 타입을 반복하는 것이 번거울 때
별칭을 이용하여 유니언 타입을 저장할 수 있는 타입을 생성사용자 정의 타입인
Combinable,ConversionDescriptor를 추가- 사용자 정의 타입에 유니언 타입을 저장해서
Combinable을 참조하게 함 - 코드의 양을 줄이고 재사용에 용이함
- 사용자 정의 타입에 유니언 타입을 저장해서
타입 별칭을 사용하여 타입을 직접 생성할 수 있음
type User = { name: string; age: number } const u1: User = { name: 'Max', age: 30 } // this works!- 타입 별칭을 사용하면 불필요한 반복을 피하고 타입을 중심에서 관리할 수 있음
단순화 전function greet(user: { name: string; age: number }) { console.log('Hi, I am ' + user.name) } function isOlder(user: { name: string; age: number }, checkAge: number) { return checkAge > user.age }단순화 후type User = { name: string; age: number } function greet(user: User) { console.log('Hi, I am ' + user.name) } function isOlder(user: User, checkAge: number) { return checkAge > user.age }
함수 & 타입
함수 반환 타입 및 무효
function add(n1: number, n2: number) {
return n1 + n2
}
function printResult(num: number): void {
console.log('Result: ' + num)
}
printResult(add(5, 12))
// let someValue: undefined;
- 반환하고자 하는 타입을 명시적으로 할당할 수 있음
- 추론이 가능한 동일한 타입이어야 함
- 변수와 마찬가지로 타입 추론에 대한 작업을 수행할 수 있도록 하는 것이 좋음
voidvsundefinedvoid- 자바스크립트에는 반환 타입이 없지만, 타입스크립트에는
아무것도 반환하지 않는 타입을 명시할 때 사용
- 자바스크립트에는 반환 타입이 없지만, 타입스크립트에는
undefined- 드물게 쓰이지만 void와 다르게
실제 값을 반환하지 않을 때사용
- 드물게 쓰이지만 void와 다르게
타입의 기능을 하는 함수
function add(n1: number, n2: number){
return n1 + n2;
}
printResult(add(5, 12));
let combineValues;
combineValues = add;
combineValues = 5; // Uncaught TypeError: combineValues is not a function
console.log(combineValues(8, 8);
- 변수에 함수를 할당해 함수를 실행
- 타입스크립트 관점에서는
combineValues가 단지any타입이라는 것만 알 수 있음 - 원하는 결과와 다르게 타입스크립트는 컴파일 에러를 발생하지 않고, 런타임 에러를 발생함
- 타입스크립트 관점에서는
let comvineValues = Function
combineValues가 함수를 할당하게 명시- 변수에 함수가 되어야 함을 명확히하기 위해 타입을 함수로 설정
let combineValues: (a: number, b: number) => number
combineValues = add
- 함수가 어떻게 동작해야 할지 명확하게 정의
- 따라서
combineValues의 매개변수가number이고 반환타입이 number임을 명확하게 정의함
- 따라서
함수 타입 및 콜백
function addAndHandle(n1: number, n2: number, cb: (num: number) => void) {
const result = n1 + n2
cb(result)
}
addAndHandle(10, 20, (result) => {
console.log(result)
})
addAndHandle함수는 두 숫자를 결합한 다음 두 숫자를 조건에 부함하는callback으로 호출- 함수 내에
callback을 전달하면 타입스크립트는 해당 결과가number가 될 것이라고 추론할 수 있고addAndHandle함수에서 인수 하나를callback으로 가져온다고 명시했으므로, 타입스크립트는result인수가number타입임을 알고 있음 - 반환값이
void타입을 명시했이므로, 호출자에서 어떤 반환문을 사용해도 무시됨
Unknown 타입
let userInput: unknown
let userName: string
userInput = 5
userInput = 'Max'
if (typeof userInput === 'string') {
userName = userInput
}
// userName = userInput; // Type 'unknown' is not assignable to type 'string'
- 타입스크립트에서 기본 제공되는
any와는 다른 타입으로써,any처럼 에러 발생없이 어떤 값이든 저장할 수 있음any보다는 제한적으로 사용됨
userName에userInput을 반환하는 경우 에러를 발생함Type 'unknown' is not assignable to type 'string'- string에 unknow 타입을 할당 할 수 없음
unknown타입을 사용할 경우, if 문을 만들어typeof userInput을 입력하고 문자열과 같은 지 검증- 추가적인 타입 검사를 통해 어떤 작업을 수행할지 명시
- unknown보다는
유니언 타입사용을 권장
Referenced