🌐 FrontEnd/TypeScript

TypeScript νƒ€μž…μŠ€ν¬λ¦½νŠΈ 기초 -1

m-ur-phy 2022. 11. 8. 20:08

 

 

μ‹œμž‘ν•˜λ©΄μ„œ

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ 기초λ₯Ό κ³΅λΆ€ν•©λ‹ˆλ‹€.

 

TypeScript λž€?

2012λ…„ λ§ˆμ΄ν¬λ‘œμ†Œν”„νŠΈκ°€ λ°œν‘œν•œ νƒ€μž…μŠ€ν¬λ¦½νŠΈ(TypeScript)λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ(JavaScript)λ₯Ό 기반으둜 정적 νƒ€μž… 문법을 μΆ”κ°€ν•œ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μž…λ‹ˆλ‹€.

 

컴파일 μ–Έμ–΄, 정적 νƒ€μž… μ–Έμ–΄

  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 동적 νƒ€μž„μ˜ 인터프리터 μ–Έμ–΄λ‘œ λŸ°νƒ€μž„μ—μ„œ 였λ₯˜λ₯Ό λ°œκ²¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 이에 λ°˜ν•΄ νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 정적 νƒ€μž…μ˜ 컴파일 언어이며 νƒ€μž…μŠ€ν¬λ¦½νŠΈ 컴파일러 λ˜λŠ” 바벨(Babel)을 톡해 μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ‘œ λ³€ν™˜λ©λ‹ˆλ‹€.
  • μ½”λ“œ μž‘μ„± λ‹¨κ³„μ—μ„œ νƒ€μž…μ„ 체크해 였λ₯˜λ₯Ό 확인할 수 있고 미리 νƒ€μž…μ„ κ²°μ •ν•˜κΈ° λ•Œλ¬Έμ— μ‹€ν–‰ 속도가 맀우 λΉ λ₯΄λ‹€λŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ½”λ“œ μž‘μ„± μ‹œ 맀번 νƒ€μž…μ„ κ²°μ •ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— 번거둭고 μ½”λ“œλŸ‰μ΄ μ¦κ°€ν•˜λ©° 컴파일 μ‹œκ°„μ΄ 였래 κ±Έλ¦°λ‹€λŠ” 단점이 μžˆμŠ΅λ‹ˆλ‹€.

 

μžλ°”μŠ€ν¬λ¦½νŠΈ μŠˆνΌμ…‹(Superset)

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μŠˆνΌμ…‹, 즉 μžλ°”μŠ€ν¬λ¦½νŠΈ κΈ°λ³Έ 문법에 νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ 문법을 μΆ”κ°€ν•œ μ–Έμ–΄μž…λ‹ˆλ‹€.
  • λ”°λΌμ„œ μœ νš¨ν•œ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ μž‘μ„±ν•œ μ½”λ“œλŠ” ν™•μž₯자λ₯Ό .jsμ—μ„œ .ts둜 λ³€κ²½ν•˜κ³  νƒ€μž…μŠ€ν¬λ¦½νŠΈλ‘œ μ»΄νŒŒμΌν•΄ λ³€ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ° 지원

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” ES6(ECMAScript 6)μ—μ„œ μƒˆλ‘­κ²Œ μ‚¬μš©λœ 문법을 ν¬ν•¨ν•˜κ³  있으며 클래슀, μΈν„°νŽ˜μ΄μŠ€, 상속, λͺ¨λ“ˆ λ“±κ³Ό 같은 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ° νŒ¨ν„΄μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

 

Static Typing(정적 타이핑)?

  • νƒ€μž…μ— λ§žλŠ” κ°’λ§Œ ν• λ‹Ή/λ°˜ν™˜ λ˜μ–΄μ•Όν•œλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.

 

μ˜ˆμ œμ™€ ν•¨κ»˜ κ³΅λΆ€ν•˜λŠ” TypeScript

ex1)

let num:number = 10; 
console.log(num); // 10

let name1 = 'happy'; // ':νƒ€μž…' 을 μƒλž΅ν•œλ‹€λ©΄ μ΄ˆκΈ°κ°’μ—μ„œ type 이 μ •ν•΄μ§„λ‹€
    // name1 = 10; // μ—λŸ¬ν‘œμ‹œ
console.log(name1); // 'happy'

function add(num1:number, num2:number){
    console.log(num1+num2);
}

//add();  // μ—λŸ¬ν‘œμ‹œ
//add(1);  // μ—λŸ¬ν‘œμ‹œ
add(1,2);  // 3 
//add(1,2,3);  // μ—λŸ¬ν‘œμ‹œ
//add('hello', 'world'); // μ—λŸ¬ν‘œμ‹œ

ex1-1)

function showItems(arr:number[]){
        arr.forEach((item) => {
            console.log(item);
        });
        
    }

    showItems([1,2,3]);
    // showItems('홍길동');  // μ—λŸ¬ν‘œμ‹œ Argument of type 'string' is not assignable to parameter of type 'number[]'.

    // let ary : string[] = ['aaa', 'bbb', 'ccc'];
    // showItems(ary); // μ—λŸ¬ν‘œμ‹œ Argument of type 'string[]' is not assignable to parameter of type 'number[]'. Type 'string' is not assignable to type 'number'.

 

 

TypeScript κΈ°λ³Έ νƒ€μž… 지정방법

let car:string = 'BMW';
let age:number = 100;
let isAdult:boolean = true;

let num:number[] = [1,2,3,4,5,];
let num2:Array<number> = [100,200,300];

let str:string[] = ['사과','λ°°','μ°Έμ™Έ','μˆ˜λ°•'];
let str2:Array<string> = ['냉μž₯κ³ ','μ •μˆ˜κΈ°','에어컨','곡기청정기'];

let obj:{name:string} = {name : 'kim'} ;
let obj2:{name:string, age:number, weight: number} = {name : 'kim', age: 50, weight: 100} ;
// let obj3:{a:string, b:number, c: number} = {name : 'kim', age: 50, weight: 100} ; // 속성 κ°’μ˜ 이름을 λ§žμΆ°μ£Όμ§€ μ•ŠλŠ”λ‹€λ©΄ λ°”λ‘œ μ—λŸ¬

let val:string | number = 'kim'; // 문자 λ˜λŠ” 숫자λ₯Ό λͺ¨λ‘ 받을 수 μžˆλ‹€
val = 1000;
console.log(val);

// car = 100;   // type μ—λŸ¬ λ°œμƒ car:string
// age = '홍길동';  // type μ—λŸ¬ λ°œμƒ age:number
// num[0] = 'κΉ€μΉ˜';  // type μ—λŸ¬ λ°œμƒ num:number[]
// str[0] = true;  // type μ—λŸ¬ λ°œμƒ str:string[]
// obj.name = 100; // type μ—λŸ¬ λ°œμƒ obj:{name:string}

| (or)

function showItems(arr:number[] | string[]){
        arr.forEach((item) => {
            console.log(item);
        });
        
    }

    showItems([1,2,3]);
    showItems(['ν”„λ¦°μŠ€μ†‘', 'μœ λ‹¨μž']);

any

let a:any = 100;
a = '홍길동';
a = true;

 

νŠœν”Œ(Tuple)

  • 직접 μ›ν•˜λŠ” type을 μ„ μ–Έν•΄μ„œ λ•Œμ— 맞좰 μ§€μ •ν•΄ 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.
type Member = [number, boolean]; // νƒ€μž…λ§Œ μ§€μ •ν•œλ‹€ (μ²«κΈ€μž λŒ€λ¬Έμž ꢌμž₯)
type Aaa = number | string;

let c:Aaa;
c = 100;
c = '홍길동';

let a:[string, number] = ['홍길동', 100];

a = ['k',1];
// a = [1,'k'];  // μ—λŸ¬λ°œμƒ -> μˆœμ„œκ°€ λ‹€λ₯΄λ‹€

let b:number[] = [1, 2, 3, 4, 5];

a[0].toUpperCase();
// a[1].toUpperCase(); // μ—λŸ¬λ°œμƒ -> μˆ«μžλŠ” toUpperCaseλ₯Ό μ‚¬μš©ν•  수 μ—†μ–΄μ„œ

let kim:Member = [123, true];
kim = [100, false];
// kim = ['홍길동', 100]; // μ—λŸ¬λ°œμƒ -> μˆœμ„œκ°€ λ‹€λ₯΄κ΅¬λ‚˜

 

Void - ν•¨μˆ˜μ—μ„œ 리턴값이 없을 λ•Œ

  • 리턴값을 μ„€μ •ν•΄μ£ΌλŠ” μ΄μœ λŠ”? μ˜¬λ°”λ₯Έ 값을 μ–»κΈ° μœ„ν•΄μ„œμž…λ‹ˆλ‹€.
function sayHello():void{
    console.log('hello');
    // return 100;
}

function sayHello2():number{
    return 100;
    // return 'hello'; // μ—λŸ¬ λ°œμƒ -> type 이 λ§žμ§€ μ•Šλ‹€
}

function sayHello3(a:number, b:number):number{
    return a+b;
}

sayHello();
console.log(sayHello2());
console.log(sayHello3(100,200));

 

ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—μ„œ λ¦¬ν„΄κ°’μ˜ type을 정해쀄 λ•Œ

const isGreater = (a: number, b: number): boolean => {
	return a > b;
}
console.log(isGreater(100,200));

 

null , undefined

  • μ–΄λ–€ 값이든 “받을 수 μ—†λ‹€” λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.
let a:null = null;
let b:undefined = undefined;

a=100; //μ—λŸ¬λ°œμƒ
b=100; //μ—λŸ¬λ°œμƒ

 

object (객체) 1

type Member = {
    name : string,
    tel : string,
    add : string
}
let kim:Member = { name:'kim', tel:'010-0000-0000', add:'μ„œμšΈ'};
// μœ„λŠ” λ‹€μŒμ™€ κ°™λ‹€ let kim:{name: string, tel: string, add: 'μ„œμšΈ'} = { name:'kim', tel:'010-0000-0000', add:'μ„œμšΈ'};
console.log(kim.name, kim.tel, kim.add);

 

object (객체) 2

type Member = {
    [key:string] : string // object 에 νƒ€μž… μ§€μ •ν•΄μ•Ό ν•  속성이 λ„ˆλ¬΄ λ§Žλ‹€λ©΄ μ΄λ ‡κ²Œ 적어주면 λœλ‹€
    // key λΌλŠ” 이름은 μž„μ˜λ‘œ μ§€μ •ν•œ 것이기 λ•Œλ¬Έμ— λ‹€λ₯Έ 이름을 쀄 수 μžˆλ‹€. (ν•˜μ§€λ§Œ 보톡 key value λ‹ˆκΉŒ 뭐)
}

let kim:Member = { name:'kim', tel:'010-0000-0000', add:'μ„œμšΈ' };
console.log(kim.name, kim.tel, kim.add);

 

μΈν„°νŽ˜μ΄μŠ€(interface)의 λ‹€μ–‘ν•œ ν™œμš©

let user:object;
// let user:{name:string, age:number}; // λ§Œλ“œλŠ” μˆœκ°„ 객체의 νƒ€μž…, μ†μ„±μ˜ νƒ€μž…λ˜ 지정을 ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.
// type Member = { name:string, age:number }
// let user:Member{}

user ={
    name : '홍길동',
    age : 30
}
console.log(user.name , user.age); // μ—λŸ¬ -> 객체의 속성에 νƒ€μž…μ΄ μ§€μ •λ˜μ§€ μ•Šμ•„μ„œ

 

μΈν„°νŽ˜μ΄μŠ€ μ‚¬μš©

// type User = {
//     name : string,
//     age : number
// }

interface User {  // type 처럼 ν˜•μ„ λ§Œλ“€μ–΄μ£ΌλŠ” μš©λ„μ΄λ‹€. κ°μ²΄λ‚˜ 객체 μ΄μƒμ˜ μš©λ„λ‘œ μ‚¬μš©ν•  λ•ŒλŠ” interfaceλ₯Ό μ‚¬μš©ν•œλ‹€.
    name : string;
    age : number; // interface 도 μ‰Όν‘œλ₯Ό μ‚¬μš©ν•  수 μžˆμœΌλ‚˜, μΌλ°˜μ μœΌλ‘œλŠ” μ„Έλ―Έμ½œλ‘ μ„ μ“΄λ‹€.
}

let user : User = {
    name : '홍길동',
    age : 30
}

user.age=10;
console.log(user.name , user.age);

 

?

  • μ‚¬μš©ν•΄λ„ 되고 μ•ˆν•΄λ„ λ˜λŠ” 속성에 ?μ˜΅μ…˜μ„ μ‚¬μš©ν•œλ‹€
interface User {
    name : string;
    age : number;
    gender? : string;
}

let user : User ={
    name : '홍길동',
    age : 30
}

user.age=10;
user.gender = 'male'; // μ΄ˆκΈ°κ°’μ„ μ£Όμ§€ μ•Šμ•˜μ§€λ§Œ gender? 둜 μ²˜λ¦¬ν•΄μ„œ μ—λŸ¬ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€
console.log(user.name , user.age);

 

readonly (읽기 μ „μš©)

  • 값을 읽을 μˆ˜λŠ” μžˆμ§€λ§Œ μˆ˜μ •ν•  μˆ˜λŠ” μ—†λ‹€ 마치 const 처럼…
interface User {
    name : string;
    age : number;
    gender? : string;
    readonly birthYear : number;
}

let user : User ={
    name : '홍길동',
    age : 30,
    birthYear : 2000
}

user.age=10;
user.gender = 'male';
// user.birthYear = 2022; //readonly μ΄κΈ°λ•Œλ¬Έμ— μ—λŸ¬λ°œμƒ
console.log(user.name , user.age, user.birthYear);

 

숫자둜 μ •μ˜λœ 속성

interface User {
    name : string;
    age : number;
    gender? : string;
    readonly birthYear : number;
    1 : string;
    2 : string;
    3 : string;
    4 : string;
}

let user : User ={
    name : '홍길동',
    age : 30,
    birthYear : 2000,
    1 : 'A',
    2 : 'B',
    3 : 'C',
    4 : 'F'
}

user.age=10;
user.gender = 'male';
//user.birthYear = 2022; //readonly μ΄κΈ°λ•Œλ¬Έμ— μ—λŸ¬λ°œμƒ
console.log(user.name , user.age, user.birthYear, user.gender, 
user[1], user[2], user[3], user[4]); // key값이 숫자인 κ²½μš°μ—λŠ” λŒ€κ΄„ν˜Έ μ—°μ‚°μžλ‘œ 접근해야함
  • μ΄λ ‡κ²Œλ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
interface User {
    name : string;
    age : number;
    gender? : string;
    readonly birthYear : number;
    [key:number] : string;
}

let user : User ={
    name : '홍길동',
    age : 30,
    birthYear : 2000,
    1 : 'A',
    2 : 'B',
    3 : 'C',
    4 : 'F'
}

user.age=10;
user.gender = 'male';
// user.birthYear = 2022; //readonly μ΄κΈ°λ•Œλ¬Έμ— μ—λŸ¬λ°œμƒ
console.log(user.name , user.age, user.birthYear, user.gender, user[1], user[2], user[3], user[4]);

 

μ—¬λŸ¬κ°œμ˜ 객체 속성을 ν•œλ²ˆμ— μ •μ˜ν•˜λŠ” 방법

type Score = 'A' | 'B' | 'C' | 'D' | 'F';   // 5개의 학점(λŒ€λ¬Έμž)만 μ‚¬μš©

interface User {
    name : string;
    age : number;
    gender? : string;
    readonly birthYear : number;
    [key:number] : Score;
    // [key:number] : 'A' | 'B' | 'C' | 'D' | 'F';    // [key:number] : string;
}

let user : User ={
    name : '홍길동',
    age : 30,
    birthYear : 2000,
   1 : 'A',
    2 : 'B',
    3 : 'C',
    4 : 'F'
}

user.age=10;
user.gender = 'male';
// user.birthYear = 2022; // readonly μ΄κΈ°λ•Œλ¬Έμ— μ—λŸ¬λ°œμƒ
console.log(user.name , user.age, user.birthYear, user.gender, user[1], user[2], user[3], user[4]);

 

ν•¨μˆ˜ μ •μ˜

interface Add {
    (x1: number, y1: number) : number; // (λ§€κ°œλ³€μˆ˜) : 리턴값 -> λ§€κ°œλ³€μˆ˜ 이름은 λ‹€λ₯Έμ΄λ¦„을 써도 아무 상관이 μ—†λ‹€.
}

const add : Add = function(x, y) {
    return x + y;
}

// 읡λͺ… ν•¨μˆ˜ 버전
// const add = function(x:number, y:number):number {
//     return x + y;
// }

console.log(add(10, 20)); // 30

interface IsAdult{
    (age:number): boolean;
} 
const kim: IsAdult = (age) => {
    return age>19;
}
console.log(kim(30));  // true