[TypeScript] 타입스크립트, 타입 종류 (tsconfig.json)
타입스크립트란
정적 타입의 컴파일 언어
- 자바스크립트 (동적 타입) : 런타임에서 동작할 때 타입 오류 확인
- 타입스크립트 (정적 타입) : 코드 작성 단계에서 타입 오류 확인
브라우저나 Node.js 환경은 타입스크립트가 직접적으로 동작할 수는 없다.
👉 자바스크립트로 변환(컴파일) 후 브라우저나 Node.js 환경에서 동작
tsconfig.json
{
"compilerOptions": {
"target" : "ES2015",
"module": "ESNext",
"moduleResolution": "Node",
"esModuleInterop": true,
"lib" : [ "ESNext", "DOM" ],
"strict": true
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}
📌 compilerOptions
타입스크립트를 자바스크립트로 변환하기 위해 어떤 옵션이 세부적으로 필요한지 결정해주는 옵션
target : "ES2015" | 컴파일 될 ES(JS) 버전 명시 | ES2015년도 버전 권장 |
module: "ESNext" | 모듈 시스템 지정 ( CommonJS, AMD, ESNext) - nodeJS에서는 CommonJS | Js의 표준 명칭인 ECMAScript의 가장 최신 버전으로 브라우저에서 사용하는 ESNext 모듈을 사용 |
moduleResolution: "Node" | 모듈 해석 방식 지정 ( Node, Classic ) | 어떤 경로를 작성할 떄 특정 폴더에 있는 index 이름을 가지는 js 파일은 선언 생략 가능 |
esModuleInterop: true | ESM 모듈 방식 호환성 활성화 여부 ( 기본 false ) |
js의 ECMAScript , 즉 ESM 방식을 사용하고 있는데 Node.js 는 common.js 방식을 사용한다. 👉 ESM 방식 + common.js 방식을 호환해서 전부 사용할 수 있는 구조로 변경 |
lib : [ "ESNext", "DOM" ] | 컴파일에서 사용할 라이브러리 지정 | ts가 js로 코드를 컴파일할 때 내부적으로 사용해야하는 라이브러리 목록 지정 |
strict: true | 더 엄격한 타입 검사 활성화 | ts 문법을 엄격하게 사용 👉 정적 타입인 ts 언어를 쓰는 의미가 명확해짐 |
📌 ESM vs CommonJS
// common.js
// ESM 방식이 아닌 Node.js에서 사용하는 CommonJS 방식으로 생성
const ohzl = {
name: 'ohzl',
age: 27
}
module.exports = { ohzl }
- CommonJS 방식
esModuleInterop 옵션을 끄게 되면 CommonJS 방식만 사용하므로 기본 내보내기 개념이 존재하지 않아서 사용할 수 없다.
import * as commonjs from './common'
옵션을 활성화해야 CommonJS 방식으로 export한 문법을 ESM 문법으로 사용 가능하다.
import commonjs from './common'
📌 include
어떤 타입스크립트 파일들을 컴파일해서 자바스크립트로 변환할 것인지,
즉 그 컴파일할 파일에 대한 경로가 어디에 있는지 배열 데이터로 목록화해서 제공
src/**/*.ts | 현재 파일 주변에 있는 src 폴더에 모든 하위 경로를 포함해서 모든 이름의 ts 파일을 포함 |
📌 exclude
타입스크립트 컴파일에서 제외할 파일 경로 목록
node_modules | 패키지를 보관하기 위한 용도이므로 js로 변환할 필요가 없음 |
타입 종류
데이터 할당이 되지 않으면 undefined로 초기 세팅이 되므로, 나중에 값 할당을 해줘야한다.
1️⃣ 문자
let str : string
let red : string = "Red"
2️⃣ 숫자
let num: number
let float: number = 3.14
let nan: number = NaN
3️⃣ 불린
let isBoolean: boolean
let isDone: boolean = false
4️⃣ Null / Undefined
let nul: null
let und: undefined
console.log(nul) // undefined
console.log(und) // undefined
null은 null로 재할당 해줘야하는데, 가동성이 좋지 않음
null / undefined는 잘 쓰이지 않는다.
5️⃣ 배열
const fruits: string[] = ['Apple', 'Banana']
const numbers: number[] = [1,2,3,4]
const union: (string|number)[] = ['Apple', 1, 2, 'Banana', 3, 4]
6️⃣ 객체
// typeof DATA = 'object'
const obj: object = {}
const arr: object = []
const func: object = function() { }
객체 뿐만 아니라 배열, 함수도 'object' 타입이 되므로 타입이 엄격해지지 않는다.
const userA: {
name: string,
age: number,
isValid: boolean
} = {
name: 'ohzl',
age: 27,
isValid: true
}
객체 데이터의 type을 명시할 때는 object 타입을 직접적으로 사용하지는 않고,
객체 속성의 타입을 각각 명시해서 사용한다.
interface User {
name: string
age: number
isValid: boolean
}
const userA: User = {
name: 'ohzl',
age: 27,
isValid: true
}
const userB: User = {
name: 'ohzl2',
age: 30,
isValid: false
}
객체 데이터는 속성과 값에 key-value 형태로 존재를 하는데,
같은 타입의 새로운 객체를 만들 때마다 타입을 지정해야하는 상황이 생길 수도 있다.
그 때, Interface를 통해 손쉽게 재활용 한다.
7️⃣ 함수
const add: (x: number. y: number) => number = function (x, y) {
return x + y
}
const add = function (x: number. y: number): number {
return x + y
}
const a: number = add(1, 2)
매개변수의 타입을 지정해주고 반환되는 값의 타입을 지정해준다.
const hello: () => void = function () {
console.log('Hello world')
}
const hello = function (): void {
console.log('Hello world')
}
const h: void = hello()
return 키워드가 없는 함수를 호출하면 undefined가 반한되므로 반환 값에는 void 타입을 지정한다.
8️⃣ Any
let hello: any = 'Hello world'
hello = 123
hello = false
모든 데이터 타입을 사용할 수 있다. 엄격성이 떨어지므로 사용을 지양한다.
9️⃣ Unknown
const a: any = 123
const u: unknown = 123
const any: any = a // 또는 u
const boo: boolean = a // 또는 u --> error
const num: number = a // 또는 u --> error
const arr: string[] = a // 또는 u --> error
const obj: { x: string, y: number } = a // 또는 u --> error
Any타입은 어떤 데이더튼 할당해도 상관없지만,
Unknown은 정확하게 어떤 데이터가 할당될지 알 수가 없으므로 '알 수 없음'으로 표시하겠다는 의미를 가진다.
위 코드처럼 any 타입인 a 를 할당하면 아래 재할당 코드에서 문제가 없지만
unknown 타입인 u를 할당하면 알 수 없는 타입의 데이터가 재할당되므로 타입에러가 발생한다.
🔟 Tuple
const tuple: [string, number, boolean] = [ 'a', 1, false ]
const tuple: [string, number, boolean] = [ 'a', 1, false, 123 ] // error !
배열의 정확한 아이템 개수와 순서를 명시를 하는 타입
배열 데이터의 개수가 달라질 수 있는 구조에서는 적합하지 않다.
const users: [number, string, boolean][]
= [[1, 'Neo', true], [2, 'Evan', false'], [3, 'Lewis', true]]
배열 데이터이지만 Tuple 타입이다.
배열 아이템의 개수와 순서를 정확하게 지정한다.
1️⃣ 1️⃣ Void
function hello(msg: string): void {
console.log(`Hello ${msg}`)
}
const hi: void = hello('world')
return 키워드를 사용하지 않으면 데이터는 undefined가 반환되지만,
타입스크립트에서는 void 타입을 사용해야 return 키워드가 없는 함수라고 해석된다.
👉 return 키워드를 명시하지 않은 함수에서 반환되는 타입
1️⃣ 2️⃣ Never
const nev: [] = [] // --> 배열에 타입을 선언해주지 않으면 never로 인식되어 아무런 값도 할당할 수 없음
nev.push(3) // error !
아무것도 할당할 수 없는 구조
직접 사용할일은 거의 없다.
1️⃣ 3️⃣ Union
let union: string|number
union = 'Hello Type'
union = 123
union = false // error
타입을 여러개 지정할 수 있으며, 여러개 사용 가능하다.
1️⃣ 4️⃣ Intersection
interface User {
name: string,
age: number
}
interface Validation {
isValid: boolean
}
const obj: User & Validation = {
name: 'Neo',
age: 20,
isValid: true
}
인터페이스의 타입이 동시에 지정이 된다.