Basic Types
기본적인 number, string, boolean 등의 타입을 지정해줄 때 : 콜론 을 이용한다
let a: number = 1;
let b: string = "i1";
let c: boolean = true
배열에 기본 타입 지정하기
배열에 타입을 지정하길 원하는 경우, 기본 타입 지정 다음에 배열 표시로 [ ] 를 붙여준다.
해당 타입 요소들로 배열을 만들겠다는 의미이다.
// array
let d: number[] = [1, 2];
let e: string[] = ["hello", "world"];
let f: boolean[] = [true];
물론, 변수를 사용할 때 꼭 타입 지정해줄 필요는 없다.
어떤 때에는 typescript가 스스로 타입을 추론하도록 하는게 좋을 수 있다.
즉, 굳이 타입을 지정을 해주지 않아도 typescript는 작동한다.
let a: number = [1, 2];
let a = [1, 2]; // 타입 추론
객체에 기본 타입 지정하기
객체에서도 타입 추론을 이용할 수도 있으나, 만일 타입을 직접 지정한다면
변수명 : { 타입지정 } = { 선언 } 형태로 이용 가능하다.
// 타입 추론
const player1 = {
name: "sryung"
}
// player1.name = 1; // error
player1.name = "eve";
// 타입 지정
const player2 : {
name: string
} = {
name: "sryung"
}
Optional Types
객체에서 어떤 key값을 가질 수도 있고, 안가질 수도 있다고 한다면?
선택적으로 값을 가지는 경우에는 key 이름 뒤에 ? 를 붙임으로써 선택적 변수(optional parameter)임을 지정할 수 있다.
// 모두가 name은 갖고 있지만, age는 선택적으로 가진다면?
const student: {
name: string,
age?: number
} = {
name: "sryung"
}
// age를 가지지 않아도 문제 없음
// age? : number | undefined
위에서는 age 에 마우스를 올릴 경우 age? : number | undefined 라는 선언이 보여진다.
때문에 만일 student.age를 조건문에서 이용하는 경우
아래처럼 undefined가 나올 상황을 대비해서 방어하는 에러가 발생하곤 한다.
// if(student.age > 10) { ... }
// ? Object is possibly 'undefined'.
// student.age가 undefined인 경우를 대비해서 경고 알림
// student.age가 존재하는지 여부를 함께 물어야만 에러 없이 실행 가능
if(student.age && student.age > 10) { ... }
Unions Types
위에서 잠시 나온 number | undefined 를 살펴보자.
데이터 타입을 1개만 가지는 것이 아닌, 다수를 가지는 경우 | 를 이용해 모두 선언할 수 있다.
// 숫자 또는 undefined
let a: number | undefined = 123;
// 문자열로 가득한 배열 또는 숫자
let b: string[] | number = 123;
한 번 정리하자면 optional types의 ? 는 | undefined 를 의미한다고 생각해도 무방하다는 것이다.
Type Alias
별칭
타입 지정하는 코드가 반복되는 경우를 위해 타입 자체를 변수로 만들어 이용한다.
type 별칭 = 타입; 형태로 이용하며. 별명을 불러올 때에는 : 타입 지정하던 것과 같이 : 별칭 을 이용한다.
type MyType = string | number;
let h: MyType = 123;
let l: MyType = "123";
일반적으로 별칭의 첫 글자는 대문자로 지정한다.
객체에 type alias 이용하기
만일 아래처럼 타입을 지정하는 경우가 있다면
const playerA : {
name: string,
age?: number
} = {
name: "Amy"
}
const playerB : {
name: string,
age?: number
} = {
name: "Bread",
age: 18
}
코드 반복을 줄이기 위해
Age, Name과 Player 라는 별칭을 만들어 이용할 수 있다.
// Type Alias 적용
type Age = number;
type Name = string;
type Player = {
name: Name,
age?: Age
}
const playerA : Player = {
name: "Amy"
}
const playerB : Player = {
name: "Bread",
age: 18
}
Age, Name 은 어디까지나 예시이며, 너무 과하게 별칭을 만드는 것은 비추천한다.
객체에 type alias 이용하기 (2)
위에서는 key로 name과 age 두개만 존재했다면, 이번에는 그보다 다수인 경우다.
"문자열로 만들어진 key들의 value가 모두 문자열이다." 의 의미로 [key: string]: string 과 같이 작성할 수 있다.
type MemberObj = {
name: string
}
let marry: MemberObj = { name: 'kim' }
// 만일, type 지정할 속성이 name 외에도 너무너무 많다면?
type MemberObj2 = {
[key: string]: string
// 글자로 된 모든 object 속성의 타입은 string
}
let tom: MemberObj2 = { name: 'lee', age: '123' }
// 귀찮게 속성마다 일일히 지정하지 않음
함수에 type 지정하기
앞서서는 let, const로 만들어진 변수에 대해서만 type 할당을 했다면, 이제는 함수의 차례다.
함수가 파라미터로는 어떤 타입을 받을 것인지, return 하는 타입이 무엇인지에 대해 각각 지정이 가능하다.
// 파라미터로 number를 받고
// number를 return 할거야
function funI(x: number): number {
return x * 2;
}
작성은 function 함수명(파라미터: 파라미터 타입): 리턴 타입 { } 과 같은 형식이 된다.
함수에 type alias 이용하기
'객체에 type alias 이용하기' 에서 이용한 예제를 다시 한 번 활용해보자.
함수 playerMaker는 문자열 name을 파라미터로 받고,
Player 형태의 object를 return 할 것임을 다음과 같이 작성할 수 있다.
type Age = number;
type Name = string;
type Player = {
name: Name,
age?: Age
}
function playerMaker(name: string): Player {
return {
name
}
}
const ryung = playerMaker("Ryung");
// ryung = { name: "Ryung" }
ryung.age = 12;
// ryung = { name: "Ryung", age: 12 }
playerMaker의 화살표 함수 형태도 한 번 보고 가자.
const playerMaker = (name: string): Player => ({ name })
클래스에 type 지정하기
class에 지정하는 방법도 은근슬쩍 한 번 보고 가자.
class User {
j: string;
constructor(k: string) {
this.j = k;
}
}
Readonly
readonly 키워드를 앞에 붙여 읽기 전용 속성 부여할 수 있다.
적어도 typescript 내에서는 선언 이후 수정할 수 없도록 보호하는 역할을 한다.
type A = {
readonly aa: number
bb?: string
}
let Ob: A = { aa: 123, bb: "hi" };
// Ob.aa = 123; // Ob.aa는 읽기 전용이라 수정 불가능
Ob.bb = "123";
배열에 readonly 이용하기
배열에 readonly를 이용하는 경우, 원본 배열을 수정하는 push와 같은 메소드도 입력할 수 없게 된다.
const numbers: readonly number[] = [1, 2, 3, 4];
// numbers.push(1); // numbers는 읽기 전용이라 수정 불가능
대신에 원본 배열을 유지하는 filter, map과 같은 메소드들은 이용이 가능하다.
const names: readonly string[] = ["1", "2"];
// names.push("3");
let a = names.filter(v => v === "1"); // ["1"]
let b = names.map(v => v === "1"); // [true, false]
Tuple
배열에서 사용하는 튜플 타입
배열을 생성할 수 있게 하는데, 최소한의 길이를 가져야 하고 특정 위치에 특정 타입이 있어야만 한다.
const TT: [string, number, boolean] = ["nico", 1, true];
// TT[0] = 1; // [0]으로는 string만을 받아야 해서 에러
튜플을 사용함으로써
항상 정해진 갯수, 원하는 순서의 요소를 가져야 하는 array 선언이 가능하다.
type Member = [number, boolean]; // 무조건 첫째는 number, boolean 받을거야
let john: Member = [123, true];
Tuple + readonly
튜플과 readonly를 결합하는 예시는 아래와 같다.
const PP: readonly [string, number, boolean] = ["nico", 1, true];
// PP[0] = "hi"; // 읽기 전용이라 수정 불가능
Any
아무 타입이나 될 수 있는 any.
비어있는 값을 지정하면 기본적으로 any 타입이 지정된다.
let a = []; // let a: any[]
any는 typescript를 빠져나오고 싶을 때 사용하는 타입이다.
타입스크립트의 타입 안정성을 유지하는 장치를 무시, 비활성화하기 때문이다.
const a: any[] = [1, 2, 3, 4];
const b: any = true;
a + b; // "1,2,3,4true"
그렇기 때문에 typesciprt 내에서 any를 사용하는 것은 권장되지 않고 있고,
typesciprt 설정에 any 사용을 막기 위해 추가할 수 있는 규칙도 존재한다.
아래에 서술되는 세가지 타입은 JavaScript에서는 사용하지 않는
TypeScript에서만 존재하는 타입이며, Type Checker와 소통하는 타입들이다.
Unknown
어떤 타입인지 모르는 변수를 전달할 때 unknown을 사용한다.
typescript가 타입 확인 작업을 강제로 시켜서 이용할 수 있다.
let a: unknown;
// let b = a + 1; // Object is of type 'unknown'
if(typeof a === 'number'){ // 조건문을 통해 number임을 확인
let b = a + 1;
}
if(typeof a === 'string'){ // 조건문을 통해 string임을 확인
let b = a.toUpperCase();
}
Void
void는 아무것도 return 하지 않는 함수를 대상으로 사용한다.
function hello(){ // function hello(): void
console.log('x');
}
const a = hello();
// a.toUpperCase(); // Property 'toUpperCase' does not exist on type 'void'
// return된 a가 없기 때문에 다음과 같은 메소드를 사용할 수 없다
보통 void는 따로 지정해주지 않으며
typescript는 해당 함수가 아무것도 return하지 않는다는 것을 자동으로 인식한다.
원한다면 function 함수명():void{ ... } 형태로 void를 지정해줄 수 있다.
Never
never는 함수가 절대 return하지 않을 때 발생한다.
예를 들어, 함수에서 예외가 발생할 때이다.
// 리턴하지 않고 오류를 발생시키는 함수 hello
function hello():never{
throw new Error("xxx");
}
그리고 타입이 두가지 일 수도 있는 상황에 발생할 수 있다.
function hello(name: string | number){
if(typeof name === "string"){
name // (parameter) name: string
} else if (typeof name === "number"){
name // (parameter) name: number
} else {
name // (parameter) name: never
// 이 코드가 절대 실행되면 안된다는 것
}
}
참고
코딩애플 - 타입스크립트 쓰는 이유 & 필수 문법 10분 정리
'TYPESCRIPT' 카테고리의 다른 글
[TYPESCRIPT] Type과 Interface의 차이점. 그리고 추상클래스 (0) | 2023.05.10 |
---|---|
[TYPESCRIPT] Class를 이용해서 객체지향 프로그래밍 해보기 (1) | 2023.05.07 |
[TYPESCRIPT] Function Call Signatures (0) | 2023.05.04 |
[TYPESCRIPT] 추론적 타입과 명시적 타입 (0) | 2023.04.26 |
[TYPESCRIPT] 타입스크립트란? 자바스크립트와의 차이점 (0) | 2023.04.25 |