- 타입스크립트의 주요 원시 타입은 모두 소문자!
타입 also in JS
- number (⇒ 숫자 타입은 이거 하나, 모든 수는 실수이다.)
- string
- boolean
- object
- 객체 선언할 때 object나 {}라고만 타입 명시해주면, (js와 다르게) 나중에 객체 속성에 접근할 때 오류가 난다.
- 컴파일러는 object타입이라는 것만 알지 속성이 뭐가 들어있는지는 모르기 때문이다
- object의 속성 타입까지 설정해줄 수도 있다
- 타입을 설정해줬다면, 속성에는 타입 선언했던것 그대로 있어야 한다
const obj:{} = {} obj.a = 1 // X
⇒ 타입 명시를 해주지 않으면 추론을 해서 위의 문제를 방지할 수 있다
const obj:{a: string} = {} // X const obj:{a: string} = {b: 1} // X const obj:{a: string} = {a: 1} // X const obj:{a: string} = {a: "abc"} // O
- 배열
- 배열의 원소의 타입은 해당 타입만 가능하다
:
요소타입[]
or Array<요소타입>
⇒ ex) number[] or Array<number>only 타스 타입
함수
- Function 함수: 매개변수 각각에 매개변수 타입을 각각 적고, 매개변수와 body 사이에 반환값 타입을 적음
function (a: string, b:number): string { return "리턴" }
- 화살표 함수: 함수 이름에 타입 지정 가능(매개변수, 반환값을 한번에)
const hello: (a:string) => string = () => {} const hello: (a:string) => string = function() {} // (a:string) => string가 함수 타입이 됨
- 함수 타입이 매개변수에 올 수도 있다
- 콜백함수에 많이 사용
const fn = (callback : (str:string) => void):void=>{ callback('콜백') } //콜백함수의 타입 : (str:string) => void
⇒ 콜백함수의 매개변수 타입, 개수에는 엄격하지만, 반환 타입은 크게 상관하지 않는다.
반환 타입 void
- 함수의 반환값이 없다면, 함수의 반환 타입에 void를 명시
- 리턴 값이 없으면 반환 값은 undefined이지만, 그렇다고 반환 타입으로 undefined를 명시하면 안됨. (값으로 undefined를 반환해야 한다는 명시이기 때문에)
- 매개변수만 타입을 정해주면 그에 따라 반환값을 추론하기 때문에, 특별한 경우가 아닌 이상 추론하도록 놔두는 것이 좋다.
const hello: (a:string) => void = () => {}
enum
- 애플리케이션에서 사용하는 전역 상수
enum 이름 {원소들}
- 배열처럼 index로 접근도 가능하고([]), 원소로 접근해서 index를 알아낼 수도 있다(.원소)
- =를 이용해 원소들에 값을 할당하면, 인덱스가 아니라 해당 값으로 매핑 된다
- 값이 숫자면, 그 이하의 원소들의 값은 차례로 그 값에서 +1, +2,, 된다
- 값이 숫자가 아니면, 모든 원소의 값들을 적어줘야 하고 값으로 접근할 수 없다
enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat} //Week[0] => Sun //Week.Sun => 0 //Week.Mon => 1 enum Month { October=10, November=11, December } // Month[10] => October // Month.November => 11 // Month.December => 12 // Month[12] => December
튜플
- 더 엄격한 배열, 타입 일치여부 뿐만 아니라 원소 개수, 원소 위치도 검사한다.
- 해당 배열은 길이 변경이 불가하다 (but. push, splice 조작은 가능함에 주의)
- 타입 추론이 아닌 명시를 통해서만 적용될 수 있는 타입이다
- 각 원소 자리의 타입을 명시해서 적용시킨다
[요소1타입, 요소2타입..]
const a: [number, string] = [4, "a"] // O const b: [number, string] = [4, "a", "123"] //X
never 타입
- 어떠한 타입도 허용하지 않는다는 의미
- 에러처리 함수에서 많이 쓰인다
- throw를 하는 함수라면, 에러 발생으로 throw 에서 멈춘고, 무언가를 반환할 확률이 0%이다.
const a:[] = [] a.push(1) // X a는 어떤 요소(타입)도 허용하지 않는 never 타입 const myError: (m:string) => never = (msg) => { throw `Error! ${msg}` }
any
- 어떤 값도 허용되는 타입
- 컴파일러는 이 타입의 변수로 뭘 하든, 타입 검사를 하지 않아 컴파일 에러가 나지 않는다(타입 추론도 xx)
- 되도록 쓰지 않는 것이 좋다. 진짜 뭐가 올지 모를 때만 사용해야함
- 상황1. any타입인 변수는 자료형이 맞지 않더라도, 특정 타입이 지정된 다른 변수의 값이 될 수 있다
- 상황2. 컴파일 에러 대신 런타임 에러가 올 수 있다
//1번 상황 let anything: any = 'hello' anything = 123 //O anything = { a: 'A'} //O anything = 'any' //O const a: string = anything //O const b: [number] = anything //O -> 원래 되면 안됨; 근데 컴파일러는 그냥 손 놓고 있음 const c: boolean = anything //O -> 원래 되면 안됨; // 2번 상황 const anyyyy: any = 123 console.log(anyyyy.toUpperCase()) // O -> 원래 되면 안됨; 근데 컴파일러는 그냥 손 놓고 있음
unknown
- any와 흡사하게 아무 타입이나 올 수 있지만, 보수적이다. (타입 추론도 당연히 되지 않음)
- 특정 타입만 허용되는 경우에 이 변수를 값으로 쓰면 unknown이라 안된다는 컴파일 에러가 남
- 타입 검사를 따로 해주면 컴파일 에러가 나지 않는다
- 역시 마구잡이로 쓰는 것은 안된다..
let unknowing: unknown = 'hello' unknowing = { a: 'A'} //O, 타입이 unknown인 변수에 값을 무엇을 할당하든 상관없음 unknowing = 'unknown' //O const a: string = unknowing //X, 할당된 값에 const b: [number] = unknowing //X, 현재 unknowning은 string 형태 const c: boolean = unknowing //X
union
타입1 | 타입2..
- 복수개의 타입이 모두 올 수 있다는 의미
- 경우에 따라 런타임 타입 검사를 코드로 쳐줘야 할 필요가 있다.
let uni: string | number | number[] uni = 'hello' uni = 123 uni = false //X uni = null //X uni = [1,2,3]
타입 alias
- 사용자가 정의하는 타입!
type 이름 = { key1: 타입1; key2: 타입2;}
type userA = { name: string; age: number; }
type numStr = number | string type numStrArray = numStr[] // 배열의 원소가 number나 string으로 이루어져야 한다 const user : numStrArray = [ 1, 2, 'a', 4, 'bb' ] // O
type AddFn = (x: number, y: number)=> number const add:AddFn = (a:number, b:number) => a+b add(1,2)
- 물음표?로 속성과 메서드를 선택으로 지정할 수 있다(있어도, 없어도 됨)
type userT = { name: string age?: number //age는 있어도, 없어도 됨 hello?: (phrase: number) => void }
- readonly로 속성을 읽기 전용으로 둘 수 있다(초기화 이후에 값 변경 불가능)
type userT = { readonly name: string //userT.name = '' 식으로 변경 불가 age: number }
- 각 속성을 구분할 때 only 줄바꿈으로 구분 가능, 외에도 세미콜론(;), 쉼표로도 구분 가능
인터섹션 타입
- 두개 이상의 타입의 합집합 타입
- 객체의 인터섹션 ⇒ 인터섹션 해준 타입들의 속성들을 모두 명시해줘야 함
- 유니온 타입들의 인터섹션 ⇒ 둘의 교집합한 것이 타입이 된다
타입1 & 타입2
type userA { name: string age: number } type userB { isValid: boolean } // O const userC: userA & userB { name: 'C', age:40, isValid:false } //X, userB의 속성이 없다 const userD: userA & userB { name: 'C', age:40, }
type Combinable = string | number type Numeric = number | boolean type Universal = Combinable & Numeric //Universal은 number 타입이 된다
- 인터페이스의 인터섹션은.. 두개의 인터페이스를 상속받는 것으로 실현 가능
interface Employee {} interface Admin {} interface ElevatedEmployee extends Employee, Admin {}
리터럴
- type으로 아예 값을 주는 것
- 유니온 타입으로 많이 쓰인다
function def(a: 1|2) {} //a는 1이나 2만 올 수 있다