
타입스크립트는 자바스크립트에 타입을 부여하여 개발 단계에서 정적 타입 검사를 통해 오류를 방지해주는 언어다.
컴파일 이후 tsconfig.json 설정에 맞게 일반 js 코드를 반환해준다.
타입 검사를 언제하나?
js: 코드 실행 도중 에러를 발견한다.
ts: 코드 실행 전 컴파일 단계에서 타입을 검사해 오류를 알려준다.
TS는
:를 사용해 타입을 정의하는 방식을 타입 표기 및 타입 주석(Type Annotation) 라고 한다
let num: number = 123;
let str1: string = 'hello'; // es6 템플릿 리터럴 O
let bool: boolean = true;
모든 타입에 하위 타입으로 취급함.
다만 tsconfig.json 에서 "strict": true 를 켜면 별도의 타입으로 취급
let nul: null = null;
let unde: undefined = undefined;
타입 뒤에 [] 를 쓰거나 <> 제네릭을 쓰는 방식
let numArr: number[] = [1, 2, 3];
// or
let numArr2: Array<number> = [1, 2, 3];
타입이 여러 개일 경우 유니온 타입 | 을 쓰면 된다
let multiArr: (string | number)[] = [1, 'hello'];
다차원 배열
let doubleArr: number[][] = [
[1, 2, 3],
[4, 5, 6],
];
ts에서 특별히 제공되는 타입
길이와 타입이 고정된 배열을 뜻함
let tup: [string, number] = ["tuple", 2];
push나pop같은 배열 메서드 사용시 컴파일 단계에서 경고가 안뜨기에 주의해야 한다.
객체 리터럴 타입 사용하여 프로퍼티에 타입을 지정해줘야 한다.
옵셔널 프로퍼티를 주고 싶으면 프로퍼티 뒤에 ?를 쓰면 된다.
let user: {
id?: number;
name: string;
} = {
id: 1,
name: '규성',
};
apiKey 처럼 바뀌면 안되는 값은 앞에 readonly 를 사용해 읽기 전용으로 바꿔야 한다.
let config: {
readonly apiKey: string;
} = {
apiKey: 'alskdhb',
};
config.apiKey = 'hacked'; // Error
객체에 object 타입을 그대로 쓰면 TS가 프로퍼티를 인식 못해 에러가 나버린다.
let users: object = {id: 1, name: "obj"}
users.name; // Error
중복되는 타입을 줄이고자 사용자가 직접 정의하는 타입 변수다.
type User = {
id: number;
name: string;
};
let user: User = {
id: 1,
name: '규성',
};
프로퍼티의 타입이 규칙적이라면 효율을 위해 인덱스 시그니쳐를 쓰면 된다.
type CountryCodes = {
[key: string]: string;
};
let countryCodes: CountryCodes = {
Korea: 'ko',
UnitedState: 'us',
UnitedKingdom: 'uk',
};
let countryCodes가 빈 객체여도 경고를 띄우지 않으니 주의
여러가지 값들에 각각 이름을 부여해 열거(특정값의 집합)해두고 사용하는 타입.
enum Role {
ADMIN = 0,
USER = 1,
GUEST = 2,
}
const user1 = {
name: '이규성',
role: Role.ADMIN, // 또는 Role[0]
};
console.log(user1);
enum에 인덱스를 지정 할 수도 있고 자동으로 할당 할 수도 있다.
컴파일 되어도 사라지지 않고 객체로 변경된다.
var Role;
(function (Role) {
Role[Role["ADMIN"] = 0] = "ADMIN";
Role[Role["USER"] = 1] = "USER";
Role[Role["GUEST"] = 2] = "GUEST";
})(Role || (Role = {}));
const user1 = {
name: '이규성',
role: Role.ADMIN,
};
console.log(user1);
export {};
모든 타입의 값을 할당할 수 있는 타입 (JS 변수타입)
타입을 확실히 모를 때 사용한다.
never 타입 외의 모든 타입에 할당이 된다.
let anyVar: any = 10;
anyVar = 'Hello';
anyVar = true;
다른 타입 메서드를 써도 에러가 아닌 undefined를 반환한다. → 에디터 경고 X (any의 문제점)
let anyVar: any = 10;
anyVar.toUpperCase(); // undefined
마치 자바스크립트를 쓰는 것과 같아져 타입스크립트를 쓰는 이유가 없어지므로 자주 쓰는 건 좋지 않다.
any 타입과 비슷하다.
모든 타입의 값을 할당할 수 있는 타입 (JS 변수타입)
타입을 확실히 모를 때 사용한다.
any 타입 외의 모든 타입에 할당이 안된다.
let unknownVar: unknown = 10;
unknownVar = 'Hello';
unknownVar = true;
다른 타입 메서드를 사용 시 에디터에서 에러가 난다고 경고해준다.
let unknownVar: unknown = 10;
unknownVar.toUpperCase(); // Error
위와 같은 에러는 타입정제(타입 좁히기)로 해결할 수 있다.
let unknownVar: unknown = 10;
if (typeof unknownVar === 'number') {
unknownVar.toUpperCase();
}
any타입에 비해 안정적으로 코드를 작성할 수 있게된다.
아무것도 없는(반환하지 않는) 타입
function func2(): void {
console.log("hello");
}
undefined 만 할당 가능하다. 암묵적 반환도 undefined 로 되기 때문. (js에선 void가 없음)
let a: void;
a = undefined;
null / undefined 과의 차이점은 리턴이 필요 없어진다.
// 기존 null 또는 undefined 는 리턴이 필수 (아니면 에러)
function func3(): null {
console.log("hello");
return null;
}
따라서 Void 타입은 아무것도 반환하지 않는 타입이다.
절대로 반환하지 않는(불가능한) 타입
void 와 차이점은 정상 종료가 되지 않음.
예) 무한루프, 예외처리 등에 쓰인다.
// 무한루프 -> 리턴 불가능
function func3(): never {
while (true) {}
}
// 예외처리 -> 리턴 불가능
function func4(): never {
throw new Error();
}
또 다른 차이점은 어떤 값이든 저장하지 못한다.
any , null , undefined 도 할당이 안되고 스트릭널체크 해도 마찬가지다.
타입스크립트는 단점을 극복한 업그레이드된 자바스크립트이다. 다만 모든 프로젝트에서 자바스크립트 대신 타입스크립트를 써야 하는 것 또한 아니다. 무작정 any 타입만 남발하면 불필요한 개발 시간만 늘어나게 된다. 기술을 선택할 때는 트렌드를 쫓는 것보다 알맞은 기술을 선택하는 것이 좋다.
지금까지 다룬 내용은 타입스크립트의 타입 개념에 대한 입문 수준이다. 타입 계층이나 동작 원리처럼 더 깊은 개념을 제대로 이해하려면 추가적인 학습이 필요하다. 아래의 출처를 통해 더 많은 정보를 참고해 보기를 추천한다.