자바스크립트의 단점을 보완하기 위해 'type system'이 추가된 언어.
생산성 높이고, 에러를 줄일 수 있음.
C#이나 Java 처럼 Type을 지정한 언어임.
참고 문서 - TypeScript HandBook
-> JS 개발자를 위한 문서.
MS사에서 제작한 언어임.
(참고로, VS code도 MS사에서 제작하여 둘을 함께 사용했을 때 개발 경험이 좋음)
🙋♂️ 타입스크립트가 존재하는 이유는?
- 자바스크립트의 타입 안정성(Type safety) 문제 때문.
- 자바스크립트는 매우 유연한 언어임.
[1, 2, 3, 4] + false
// '1,2,3,4false'
-> 배열과 boolean 타입이 모두 string이 되어버림.
위와 같은 말도 안되는 상황도 허용해주기 때문에 타입 안정성이 ❌
-> TypeScript에서는 런타임 이전에 에러를 발생시켜줌.
-> JS와 비교해보면, typescript는 기본적으로 strict 모드가 적용되어 있다.
TypeScript는 런타임 이전에 에러를 감지하고, 만약 에러가 있다면 JavaScript로 컴파일링 하지 않는다.
const yjin = {
name: 'thisis',
age: 24,
}
[1,2,3,4] + true
// js에서는 '1,2,3,4true` 로 정상 실행
const devide = (a, b) => {
return a / b;
}
devide(3); // ❗️ error
함수 인자의 타입을 지정해줄 수 있음.
const devide = (a:number, b:number) => {
return a / b;
}
devide('hello', 'hi'); // ❗️ error - number 형이 아님
타입 변환하려고 할 때, 막아줄 수 있음.
const player = {
age: 23
}
player.age = true; // ❗️ error -
변수 선언시 어떤 타입인지 명시해줘야 함.
🔻 변수 선언시
- 데이터와 변수 타입을 명시적으로 정의
- 자바스크립트처럼 변수만 생성하고 넘어가도 OK -> TS가 알아서 추론해줌. ✅ [권장]
-> 타입 지정을 해주지 않아도 알아서 Type이 지정됨.
❔ 만약 타입을 지정해준다면?
let greeting : number = "hello"
-> number로 지정했는데 string을 대입해서 에러 발생함.
: number
에 해당하는 부분이 type system 이다.
가독성을 위해 보통 생략하는 것이 좋음. (특정 케이스 제외)
let nums = [1,2,3,4,5]; // number[]
let jobs = ['designer', 'developer', 'engineer']; // string[]
🔻 여러 타입이 섞여있는 배열은 OR|
로 모든 타입이 표기된다.
만약 배열의 타입이 아닌 다른 타입을 push 하려고 하면, 에러가 발생한다.
let nums = number[] = [];
nums.push(1);
nums.push("1"); // ❗️ error
const team = {
designer: 'injung',
frontEnd: 'yjin',
backEnd: 'thisisyjin'
}
: {}
로 적어줘야 한다.const player : {
name: string
age: number
} = {
name: 'yjin',
age: 23
}
JS primitive 타입.
객체의 특정 필드는 필수가 아닌 optional 로 하고 싶다면?
const player : {
name: string
age?: number
} = {
name: 'yjin',
// age가 없어도 되고 있으면 number이여야 함.
}
프로퍼티 키 뒤에 ?
를 붙여주면 옵셔널한 필드로 설정 가능.
const player : {
name: string
age?: number
} = {
name: 'yjin',
age: 9
}
if (player.age < 10) { // ❗️ error : Object is possibly 'undefined'.
console.log('you are a child');
}
만약 여러개의 객체에 위와 같은 조건을 똑같이 적용해야 할 때,
일일히 코드를 여러번 작성하는 것은 매우 비효율적이다.
-> Type Aliases
를 이용하자.
📌 Alias = 별명.
// 🔻 Type Alias 선언
type Player = {
name: string,
age?: number
}
const yjin : Player = { // 그냥 :string 해주듯이 사용하면 됨.
name: 'Yjin'
}
const injung : Player = {
name: 'Injung'
}
...
function playerMaker(name:string) {
return {
name
};
}
const yjin = playerMaker('Yjin');
yjin.age = 23; // ❗️ error -
-> 리턴하는 객체에 name 프로퍼티만 존재하므로 에러가 발생함.
function playerMaker(name:string, age?:number) {
return {
name,
age
};
}
const yjin = playerMaker('Yjin');
-> 마찬가지로 인수로 받는 age에 ?를 붙여서
optional property를 설정해주면 됨.
함수 인자가 아닌 함수 자체에 type을 지정해줌
type Player = {
name: string,
age?: number
}
function playerMaker(name:string) : Player {
return {
name
}
}
함수 실행문 전에 : Player 을 붙여줌. (alias)
const playerMaker = (name:string) : Player => ({name})
const yjin = playerMaker('yjin');
yjin.age = 23;
마찬가지로 함수 블록 전에 : Player 을 붙여준다.
interface People {
name: string
age: number
}
type PeopleInterface {
name: string
age: number
}
interface PeopleInterface {
name: string
age: number
}
// 1. 동일 인터페이스 - 선언적 확장 가능 ✅
interface PeopleInterface {
gender: string
}
// 2. 다른 인터페이스로 - extends로 확장
interface StudentInterface extends PeopleInterface {
school: string
}
type PeopleType = {
name: string
age: number
}
// 다른 타입으로 확장만 가능.
type StudentType = PeopleType & {
school: string
}
❗️ 참고 - [yceffort.kr](https://yceffort.kr/2021/03/typescript-interface-vs-type
type Player = {
readonly name: string,
age: number
}
🔻 Example
type Player = {
readonly name: string,
age?: number
}
const playerMaker = (name:string) : Player => ({name})
const yjin = playerMaker('yjin');
yjin.name = 'change';
일반 변수(배열)에서도 사용 가능.
const numbers: readonly number[] = [1, 2, 3];
numbers.push(4); // ❗️ error
❗️ 주의 - readonly는 배열이나 객체의 프로퍼티에만 사용할 수 있음.
array 생성 - 최소 길이 / 특정 위치에 특정 타입
const player: [string, number, boolean] = [
'yjin',
23,
true
]
readonly
적용도 가능함. (수정 불가)const a : undefined = undefined;
const b : null = null;
const empty = []; // any
typescript
로부터 벗어나고 싶을 때 사용하면 됨.const a : any[] = [1, 2, 3, 4];
const b : any = true;
console.log(a + b); // 1,2,3,4true
let a:unknown;
let b = a + 1; // ❗️ error - Object is of type 'unknown'
if (typeof a === 'number') {
let b = a + 1;
}
= void = 비어있는 것
= 아무것도 리턴하지 않는 함수.
function hello(): void {
console.log('hello!')
}
자주 사용되지는 않음.
function hello(): never {
return 'hello'; // ❗️ error - Type 'string' is not assignable to type 'never'
}
function hello(): never {
throw new Error("hello");
}
function hello(name: string|number) {
if (typeof name === 'string') {
// name은 string
} else if (typeof name === 'number') {
// name은 number
} else {
// ❗️ name은 never
}
}