자바스크립트

 

 

 

강의 목록  :      https://www.youtube.com/playlist?list=PLZKTXPmaJk8KhKQ_BILr1JKCJbR0EGlx0

 

 

 

타입스크립트 테스트 사이트  :   https://www.typescriptlang.org/ko/play

 

typescript  설치

 

1)노드 설치 typescript

$npm init

$ npm install -g typescript

 

 

2)버전 확인

$ tsc -v

$ tsc --init

 

3) tsconfig.json을 적용하려면 아래와 같이 트랜스파일링하도록 한다

$ tsc

테스트 파일 생성

// person.ts
class Person {
  private name: string;

  constructor(name: string) {
    this.name = name;
  }

  sayHello() {
    return "Hello, " + this.name;
  }
}

const person = new Person('Lee');

console.log(person.sayHello());

 

테스트

$ tsc
$ node person

 

4)

--watch 또는 -w 옵션을 사용하면 트랜스파일링 대상 파일의 내용이 변경되었을 때 이를 감지하여 자동으로 트랜스파일링이 실행된다.

$ tsc --watch

또는 아래와 같이 tsconfig.json에 watch 옵션을 추가할 수도 있다.

{
  // ...
  "watch": true
}

 

Prettier VSC에서 설치 

 

 

 

리액트 설치 :

#npm
npm install typescript @types/node @types/react @types/react-dom @types/jest @types/react-router-dom
 
#yarn
yarn add typescript @types/node @types/react @types/react-dom @types/jest @types/react-router-dom

 

 

참조 : https://macaronics.net/index.php/m04/react/view/1905

https://any-ting.tistory.com/93

 

 

 

 

 

 

 

1. 타입스크립트를 쓰는 이유를 알아보자

 

TypeScript는 정적 타입을 지원하므로 컴파일 단계에서 오류를 포착할 수 있는 장점이 있다.

명시적인 정적 타입 지정은 개발자의 의도를 명확하게 코드로 기술할 수 있다.

이는 코드의 가독성을 높이고 예측할 수 있게 하며 디버깅을 쉽게 한다.

 

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

// add();
// add(1);
add(1,2);
// add(3,4,5);
// add(1,"world");
// add()

 

 

 

 

 

 

2. 기본 타입 

 

예1)

let car ="bmw";

let age:number =30;
let isAdult:boolean =true;
let a:number[] = [1,2,3];
let a2:Array<number> =[1,2,3];


let week1:string[] =['mon', 'tue', 'wed'];
let week2:Array<string> =['mon', 'tue', 'wed'];

 

예2)

//튜틀 (Tuple)

let b:[string, number];

b=['z' ,1];
//b2=[1,'z']; //오류

b[0].toLowerCase();
//b[1].toLowerCase(); //오류

 

 

예3)

//void 
function sayHello():void{
    console.log("hello");
}


//never  끝나지 않는 함수
function showError():never{
    throw new Error();
}

function infLoop():never{
    while(true){
        //do something...
    }
}

//enum
enum Os{
    Window =3,
    IOS =10,
    Android
}

console.log(Os['IOS']);

enum Os2{
    Window ='win',
    IOS ='ios',
    Android='and'
}

let myOS:Os2;


//null, undefined
let a:null=null;
let b:undefined=undefined;


 

 

 

 

 

 

 

 

 

3. 인터페이스(interface) 

 

 

예1)

 

// let user:object;

// user={
//     name:'xx',
//     age:30
// }

// console.log(user.name);
//=>  변경


//? 있어도 되거나 없어도 되거나.
//readonly 읽기 전용

// 1? :string;
// 2? :string;
// 3? :string;
// 4? :string;
//==> 다음과 같이 변경할 수 있다. [grade:number] :string; 
//grade 는 임의 변수로 number을 필요로 하고 string 을 값으로 받을 수 있는 properties 을 여러개 받을 수 있다.

type Score = 'A' | 'B' | 'C' | 'F';
interface User{
    name: string;
    age :number;
    gender?:string;
    readonly birthYear:number;
    [grade:number] :Score;
}



let user :User ={
    name:'xx',
    age:30,
    birthYear:2000,
    1:'A',
    2:'B'
}


user.age=10;
user.gender ="male";
//user.birthYear=1900; //=> 오류

console.log(user.age);

 

 

예2)

interface Add{
    //(파라미터 숫자1, 파라미터 숫자1): 반환값 숫자 
    (num1:number, num2:number) : number;
}


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

add(10, 20);


interface IsAdult{
    (age:number):boolean;
}

const a:IsAdult=(age)=>{
    return age>19;
}

a(33);

 

 

예3)implements

//implements
interface Car{
    color:String;
    wheels:number;
    start():void;
}

class Bmw implements Car{
    color;
    wheels=4;

    constructor(c:String){
        this.color=c;       
    }

    start(){
        console.log("go....");
    }
}

const b=new Bmw('green');

console.log("b: ", b);
b.start();

 

 

예4)implements   extneds

//implements  extends
interface Car{
    color:String;
    wheels:number;
    start():void;
}

interface Benz extends Car{
    door:number;
    stop():void;
}

const benz : Benz={
    door:5,
    stop(){
        console.log("stop");
    },

    wheels:4,
    color:"black",    
    start(){
        console.log("start");
    }
}

 

예5)

//implements  
interface Car{
    color:string;
    wheels:number;
    start():void;
}

interface Toy{
    name:string;
}

interface ToyCar extends Car, Toy{
    price:number;
}

 

 

 

 

 

4. 함수

 

 

예1)

//함수

//반환값 number
function add0(num1:number, num2 :number):number{
    return num1+num2;
}

//리턴값이 없을 경우
function add1(num1:number, num2 :number):void{
    console.log(num1+num2);
}

function hello(name?:string){
    return `Hello, ${name||"world"}`;
}


// (parameter) name: string
// function hello2(name="world"){
//     return `Hello, ${name}`;
// }
function hello2(name="world"){
    return `Hello, ${name}`;
}

const result=hello();
const resul2=hello("Sam");
console.log(result, resul2);

const result3=hello2();
const resul4=hello2("Sam");
console.log(result3, resul4);



 

 

예2)

//함수

function hello(name:string, age?:number):string{
    if(age!==undefined){
        return `Hello, ${name} . You are ${age}.`;
    }else{
        return `Hello ,${name}`;
    }
}

console.log(hello("Sam"));
console.log(hello("Sam", 30));



function hello2(age:number|undefined , name:string ):string{
    if(age!==undefined){
        return `Hello, ${name} . You are ${age}.`;
    }else{
        return `Hello ,${name}`;
    }
}

console.log(hello2(30, "Sam"));
console.log(hello2(undefined,"Sam"));

 

 

예3)

//함수

function add(...nums:number[]):number{
    return nums.reduce((result, num) => result+num, 0);
}



add(1,2,3); //6
add(1,2,3,4,5,6,7,8,9,10) ; //55

 

 

예4)

//함수

interface User{
    name:string;
}

const Sam:User={
    name:'Sam'
}

function showName(this:User ,age:number, gender:'m'|'f'){
    console.log(this.name, age, gender);
}

const a =showName.bind(Sam);
a(30, 'm');

 

 

예5)

//함수

interface User{
    name:string;
    age:number;
}


//매개변수가 다를 때 다음과 같이 오버로드 작성
function join(name:string, age:string):string;
function join(name:string, age:number):User;
function join(name:string, age:number|string) :User|string{
    if(typeof age ==="number"){
        return{
            name,
            age
        };
    }else{
        return "나이는 숫자로 입력해 주세요.";
    }
}

const sam: User =join("Sam", 30);
const jane:string =join("Jane", "30");

 

 

 

 

 

 

5. 리터럴, 유니온/교차 타입

 

예1)

// literal Type

const userName1 ="Bob";
let userName2:string|number ="Tom";

userName2 =3;

type JOb = "police" | "developer" | "teacher";

interface User{
    name :string;
    job:JOb;
}

const user :User={
    name:"Bob",
    job:"developer"
}

interface HighSchoolStudent{
    nanme:string;
    grade:1 | 2 |3;
}

 

 

예2) 식별 가능한 Union Type

// Union Type

interface Car{
    name:"car",
    color:string;
    start():void;
}

interface Mobile{
    name:"mobile";
    color:string;
    call():void;
}



function getGift(gift:Car | Mobile){
    console.log(gift.color);

    if(gift.name==="car"){
        gift.start();
    }else{
        gift.call();
    }
}

 

 

 

예3) Intersection Types

// Intersection Types

interface Car{
    name:string;
    start():void;
}

interface Toy{
    name:string;
    color:string;
    price:number;
}

//Car 와 Toy 모든 변수를 입력 해줘야 한다.
const toyCar : Toy & Car ={
    name:"타요",
    start(){},
    color:"blue",
    price:1000
}

 

 

 

 

 

 

 

 

6. 클래스 Class

 

예1)

//멤버 변수선언 또는 변수앞에 public 선언,  또는 readOnly

class Car{
    
    //color:string;

    constructor(public color:string){
        this.color=color;
    }
    
    start(){
        console.log("start");
    }
}


const bmw =new Car("red");

 

 

 

예2) 접근 제한자(Access modifier) - public , private , protected  

static

//접근 제한자(Access modifier) - public , private , protected

/*****************************************************
1) public - 자식 클래스, 클래스 인스턴스 모두 접근 가능
  접근 제한자를 붙이지 않을 경우 기본값 public

2)protected - 자식 클래스에서 접근 가능


3)private - 해당 클래스 내부에서만 접근 가능
private은  # 으로 대체 가능

**************************************************/
/*****************************************************
 static 는 클래스명으로 접근

**************************************************/

class Car{
    // #name:string ="car";
    // private name:string ="car";
    public name:string ="car";
    color:string;
    static wheels =4;
    constructor(color:string){
        this.color=color;
    }
    start(){
        console.log("start");
        console.log(this.name);
        console.log("start  wheels :",Car.wheels);
    }
}

class Bmw extends Car {
    constructor(color:string){
        super(color);        
    }
    showName(){
        //console.log("부모 name:",super.name);
        console.log("부모 name:",this.name);
        console.log("showName  wheels :",Car.wheels);
    }
}

const z4 =new Bmw("black");

console.log(z4.name);
z4.showName();
z4.start();
z4.name="zzz3";

 

 

예3)추상 class

//추상 class
abstract class Car{
    color :string;
    constructor(color:string){
        this.color=color;
    }    
    start(){
        console.log("start");
    }
    
    abstract doSomething():void;
}


//추상 클래스 new 안되고 상속을 통해서만 가능
// const car =new Car("red");

class Bmw extends Car{
    constructor(color:string){
        super(color);
    }
    doSomething(){
        console.log("추상클래스는 구체적인 기능 명시 해야 한다.");
    }
}

const z4=new Bmw("black");
console.log(z4);
z4.doSomething();

 

 

 

 

 

 

 

7. 제네릭 Generics

 

 

 

예1)

//Generic

function getSize(arr: number[] | string[] | boolean[] | object[]) :number{
    return arr.length;
}

// => 제네릭으로
function getSize2<T>(arr:T[]) :number{
    return arr.length;
}


const arr1=[1,2,3];
const arr2=["a","b", "c"];
const arr3=[false,true,true];

console.log("getSize 1 : ", getSize(arr1));
console.log("getSize 1 : ", getSize(arr2));
console.log("getSize 1 : ", getSize(arr3));




console.log("제네릭 getSize 2 : ", getSize2<number>(arr1));
console.log("제네릭 getSize 2 : ", getSize2<string>(arr2));
console.log("제네릭 getSize 2 : ", getSize2<boolean>(arr3));

 

 

예2)

interface Mobile<T>{
    name:string;
    price:number;
    option:T;   
}


const m1:Mobile<object> ={
    name:"s21",
    price:1000,
    option:{
        color:"red",
        coupon:false
    }
}

const m2:Mobile<{color:string; coupon:boolean}> ={
    name:"s21",
    price:1000,
    option:{
        color:"red",
        coupon:false
    }
}


const m3:Mobile<string> ={
    name:"s20",
    price:900,
    option:"900"
}

 

 

예3)

interface User{
    name:string;
    age:number;
}

interface Car{
    name:string;
    color:string;
}

interface Book{
    price:number;
}

const user:User ={name:"a", age:10};
const car:Car ={name:"bmw", color:"red"};
const book :Book ={price:3000};

function showName<T extends {name:string}>(data:T):string{
    return data.name;
}

showName(user);
showName(car);
//showName(book); //오류

 

 

 

 

 

 

8. 유틸리티 타입 Utility Types

 

 

예1) keyof

// keyof

interface User{
    id:number;
    name:string;
    age:number;
    gender:"m" |"f";    
}

type UserKey = keyof User;  // 'id' | 'name' | 'age' | 'gender' 같은 의미

const uk:UserKey= "id";


 

 

예2) Partial<T>

// Partial<T> 있거나 없거나 되는  ? 와 같다.

interface User{
    id:number;
    name:string;
    age:number;
    gender:"m" |"f";    
}

/**
interface User{
    id?:number;
    name?:string;
    age?:number;
    gender?:"m" |"f";    
}
 */



let admin:Partial<User>={
    id:1,
    name:"Bob",
}

 

 

예3)   Required<T>

// Required<T> 는 모든 properties 필수로 변경해서 반드시 입력해야 한다.


interface User{
    id:number;
    name:string;
    age?:number;    
}



//==> age 를 입력하지 않으면 오류
let admin:Required<User>={
    id:1,
    name:"Bob",
    age:33
}

 

 

예4)Readonly<T>

// Readonly<T> 할당만 가능하고 수정은 불가


interface User{
    id:number;
    name:string;
    age?:number;    
}



let admin:Readonly<User>={
    id:1,
    name:"Bob",
}


//오류
//admin.id=4;

 

 

예5)  Record<K,T>

// Record<K,T>

/*
interface Score{
   "1" : "A" | "B" | "C" | "D";
   "2" : "A" | "B" | "C" | "D";
   "3" : "A" | "B" |"C" | "D";
   "4" : "A" | "B" |"C" | "D";
}

const score:Score={
    1:"A",
    2:"C",
    3:"B",
    4:"D",
}

*/
//=>다음과 같이 변경

type Grade="1"|"2"|"3"|"4";
type Score="A" | "B" | "C" | "D"|"F";

const score:Record<Grade,Score>={
    1:"A",
    2:"C",
    3:"B",
    4:"D",
}



interface User{
    id:number;
    name:string;
    age:number;
}


function isValid(user:User){
    const result:Record<keyof User, boolean> = {
        id:user.id >0,
        name:user.name !=="",
        age:user.age>0
    };
    return result;
}



 

 

예6) Piock<K,T>

// Piock<K,T> 특정값 만 선택해서 사용

interface User{
    id:number;
    name:string;
    age:number;
    gender: "M" |"W";
}

const admin:Pick<User, "id"|"name"> ={
    id:0,
    name:"Bob",
}

 

 

예7)  Omit<K,T> 특정값 만 제외하고 사용 가능

// Omit<K,T> 특정값 만 제외하고  사용 가능

interface User{
    id:number;
    name:string;
    age:number;
    gender: "M" |"W";
}

const admin:Omit<User, "age"|"gender"> ={
    id:0,
    name:"Bob",
}

 

 

예8)  Exclude<T1,T2> Omit 과 유사하나 Exclude 는 타입으로 제거

// Exclude<T1,T2> Omit 과 유사하나 Exclude 는 타입으로 제거


type T1= string | number | boolean;
type T2 =Exclude<T1, number | string>;


//type T2 = boolean
//Exclude<T1, number | string> 로제거한 T2 는 boolean 타입만 사용가능

 

 

예9) NonNullable<Type>   null ,  undefined  제거

//NonNullable<Type>   null ,  undefined  제거

type T1 = string | null | undefined | void;
type T2 = NonNullable<T1>;


//type T2 = string | void

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

미인이란 처음으로 볼 때는 매우 좋다. 그러나 사흘만 계속 집안에서 상대해 보면 더 보고 싶지가 않게 된다. -버나드 쇼

댓글 ( 4)

댓글 남기기

작성