강의 목록 : 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
댓글 ( 4)
댓글 남기기