[Typescript] 타입스크립트 기초 - 타입
타입스크립트는 타입에 너무나도 관대한 JS의 단점을 보완하고자 MS에서 만든 언어입니다.
전체적으로 JS와 비슷하나, 언어 이름이 'Type'script인 만큼 타입이 맞지 않을 경우 에러메세지를 띄워주어 실수를 줄여준다는 특징이 있습니다.
아직 많이 써보진 않았지만 저도 언어를 사용해보면서, 개발자 경험이 향상되는 것을 느낄 수 있어 좋았습니다!
타입스크립트의 타입
배열은 자료형[], 숫자는 number, 문자열은 string, 논리타입은 boolean입니다.
예를 들어 숫자배열일 경우 number[] 타입이 됩니다.
타입은 :과 타입명을 변수 뒤에 붙여 표기합니다.
const myName: string = "mingbee";
Optional
TS는 옵셔널 타입이 존재하는데, 해당 속성을 정의하지 않아도 되는 경우 옵셔널타입으로 나타냅니다.
객체에서 선택적으로 입력받는 프로퍼티에 ?를 붙여 옵셔널한 것임을 나타낼 수 있습니다.
옵셔널 타입에 값을 넣지 않을 경우, 해당 프로퍼티는 undefined가 됩니다.
const player : {
name: string,
age?:number
} = {
name: "nico"
}
위 코드의 경우, {}가 2개가 있습니다.
앞의 {} 안에 player 객체의 타입을 정의한 후, 뒤쪽 {} 안에 값을 넣습니다.
옵셔널 타입의 프로퍼티를 사용할 때는 해당 프로퍼티가 undefined는 아닌지 한 번 더 확인하고 써야 합니다.
이렇게 말입니다.
// player.age가 undefined 아닌지 확인
if(player.age && player.age < 10) {
}
Any
any는 타입이 정의되지 않았을 때 쓰는 타입입니다.
비어있는 값들을 쓰면 기본값이 바로 any가 됩니다.
let a = []
이렇게 쓸 경우 a는 any의 배열이 됩니다.
any를 쓰면 TS의 타입 보호로부터 벗어나게 됩니다.
const a: any[] = [1,2,3,4];
const b: any = true;
a + b;
any로 타입을 정의할 경우 이렇게, 타입 상관 없이 행해지는 연산을 허용시킵니다.
이 경우 마치 JS처럼 연산이 됩니다.
unknown
어떤 타입인지 모르는 변수는 unknown으로 정의합니다.
특정 API로부터 데이터를 받을 때, 타입을 모르는 데이터를 받게되면 unknown을 사용합니다.
let a:unknown
if(typeof a === 'number'){
let b = a + 1
}
if(typeof a === 'string'){
let b = a.toUpperCase()
}
// let b = a + 1
unknown으로 데이터를 받을 경우, if문과 typeof를 사용해 해당 데이터를 처리할 수 있습니다.
void
아무것도 return하지 않는 함수에서 반환 타입은 void가 됩니다.
C 등의 언어에서 많이 본 타입입니다ㅎㅎ
function hello() {
console.log('x')
}
const a = hello()
// a.toUpperCase()
위의 함수는 : void를 쓰지 않았지만, 아무 것도 반환하지 않을 경우 자동으로 void 함수로 인식합니다.
위 함수의 경우 'x'를 출력하고, 반환은 void가 됩니다.
void는 반환값이 빈 함수이므로 주석과 같은 처리가 불가능합니다.
never
함수가 return하지 않고 에러를 발생시킬 때 해당 함수는 never 타입이 됩니다.
never를 이용해 에러 처리를 하는 방법은 다음과 같습니다.
function hello():never {
throw new Error("zzz")
// return "a"
}
먼저, 이렇게 직접적으로 에러를 발생시킬 때 이 함수는 never 타입이 됩니다.
function temp(name:string|number):never {
if(typeof name === "string"){
name
} else if(typeof name === "number"){
name
} else {
name
}
}
다음으로, if문과 typeof로 에러를 처리할 수 있습니다.
if 안에서는 string형의 name을, else if 안에서는 number형의 name 반환할 것입니다.
하지만 파라미터가 제대로 전달되지 않아 이상한 타입을 받았을 때,
if문에서 else로 받은 후 반환하면, 해당 name은 never 타입이 됩니다.
Type Alias(별칭)
TS는 같은 타입을 여러 번 정의해야 할 때, 타입 자체를 정의해놓고 여러번 사용할 수 있습니다.
이를 Type Alias라고 합니다.
type Player = {
name: string,
age?:number
}
이렇게 Player라는 객체 타입을 한 번 정의해놓으면
const player : Player = {
name: "mingbee"
}
이렇게 새로운 Player 객체를 생성할 때 아까 지정해놓은 타입을 갖다쓸 수 있습니다.
Type Alias를 함수에 적용할 수도 있습니다.
type Player = {
name: string,
age?:number
}
function playerName1(name:string) : Player {
return {
name
}
}
const playerName2 = (name:string) : Player => ({name})
const mingbee = playerMaker1("mingbee")
mingbee.age = 12
이렇게 여러 형태로 함수에 적용 가능합니다.
다만 화살표 함수에서 리턴을 ({}) 형태로 하는 것이 이상해 보일 수도 있는데, 이는 화살표 함수에서 {} 안에 실행문을 쓴다는 의미로 {}를 쓴 것이 아니라, 객체를 리턴한다는 것을 알려주기 위해 ()로 한 번 더 감싼 것입니다.
Readonly
TS는 특정 속성을 수정할 수 없게 readonly를 지정할 수도 있습니다.
Alias에서 프로퍼티 이름 앞에 readonly를 쓰면 됩니다.
type Player = {
readonly name:string
age?:number
}
const playerMaker = (name: string): Player => ({name})
const mingbee = playerMaker("mingbee")
// mingbee.name = "mingming"
이렇게 쓸 경우 주석처럼 수정했을 때 에러가 납니다.
const numbers: readonly number[] = [1, 2, 3, 4]
// numbers.push(1)
배열에도 적용할 수 있습니다.
주석처럼 정의 이후에 push를 할 경우 에러가 납니다.
이렇게 readonly로 수정을 막으면 immutability(불변성)을 부여할 수 있습니다. 하지만 JS로 변환될 때는 그냥 배열로 바뀌게 됩니다...
Tuple
정해진 개수와 타입 순서에 따라 선언된 배열을 튜플이라고 합니다.
튜플에 필요한 타입을 순서대로 작성하면 해당 순서대로 작성된 타입이 모두 들어가게 정의해야 합니다.
const player: [string, number, boolean] = ["nico", 1, true]
위 코드의 경우는 string, number, boolean 타입이 모두 순서대로 들어가야 합니다.
이는 최소 3개의 항목을 필요로 한다는 뜻도 됩니다.
튜플은 수정할 때도 앞에서 작성한 타입을 바꾸면 안 됩니다.
튜플에 readonly를 사용할 때는 타입 선언 부분에 배열 앞에 키워드를 쓰면 됩니다.
const player: readonly [string, number, boolean] = ["nico", 1, true]