$ mkdir ts-practice # ts-practice라는 디렉터리 생성
$ cd ts-practice
$ yarn init -y
ts-practice 디렉토리에 package.json이라는 파일이 생성
$ yarn global add typescript
프로젝트 디렉토리 안에서 tsc --init # tsconfig.json파일 자동 생성
src/practice.ts
$ tsc
interface Shape{
getArea():number;
// Shape interface에는 getArea라는 함수가 꼭 있어야하며 해당 함수의 반환값은 숫자
}
class Circle implements Shape{
radius:number; // 멤버 변수 radius 값을 설정
constructor(radius:number){
this.radius=radius;
}
getArea(){
return this.radius*this.radius*Math.PI;
}
}
// $ tsc
// $ node dist/practice
interface Person{
name: string;
age?: number;
}
interface Developer{
name: string;
age?: number;
skills: string[];
}
// interface Developer extends Person{ skills: string[]; }
const person:Person={
name: '김사람',
age: 20
};
const expert:Developer={
name: '김개발',
skills: ['javascript', 'react']
};
// &는 intersection으로서 두개 이상의 타입들을 합쳐준다.
type Developer=Person&{
skills: string[];
};
// 예1
function merge<A,B>(a:A, b:B):A&B{
return{
...a,
...b
};
}
const merged=merge({foo:1},{bar:1});
// 함수에서 Generics를 사용하면 파라미터로 다양한 타입을 넣을 수 있고
// 타입 지원을 지켜낼 수 있다
// 예2
function wrap<T>(param:T){
return{
param
}
}
const wrapper=wrap(10);
// interface에서 Generics 사용하기
interface Items<T>{
list:T[];
}
const items: Items<string>={
list:['a','b','c']
};
// type에서 Generics 사용하기
type Items<T>={
list: T[];
};
const items: Items<string>={
list:['a','b','c']
};
// 클래스에서 Generics 사용하기
class Queue<T>{
list: T[]=[];
get length(){
return this.list.length;
}
enqueue(item:T){
this.list.push(item);
}
dequeueu(){
return this.list.shift();
}
}
const queue= new Queue<number>();
queue.enqueue(0);
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.enqueue(4);
console.log(queue.dequeue());
console.log(queue.dequeue());
console.log(queue.dequeue());
console.log(queue.dequeue());
console.log(queue.dequeue());
// $ tsc
// $ node dist/practice
// 0
// 1
// 2
// 3
// 4
$ npx create-react-app ts-react-tutorial --typescript
// src/Greetins.tsx
import React from 'react';
type GreetingsProps={
name:string;
};
const Greetings: React.FC<GreetingsProps>=({name})=>(
// const Greetings=({name}:GreetingsProps)=>(
<div>Hello, {name}</div>
);
export default Greetings;
// src/Greetings.tsx
import React from 'react';
type GreetingsProps={
name:string;
onClick: (name:string)=>void;
};
function Greetings({name, onClick}:GreetingsProps){
const handleClick=()=>onClick(name);
return(
<div>
Hello, {name}
<div>
<button onClick={handleClick}>Click Me</button>
</div>
</div>
);
}
export default Greetings;
// App.tsx
import React from 'react';
import Greetings from './Greetings';
const App: React.FC=()=>{
const onClick=(name:string)=>{
console.log(`${name} says hello`);
};
return <Greetings name="Hello" onClick={onClick}/>;
};
export default App;
// $ yarn start
// src/Counter.tsx
import React, {useState} from 'react';
// Generics를 사용하지 않아도 알아서 타입을 유추
function Counter(){
const [count, setCount] = useState(0);
const onIncrease=()=>setCount(count+1);
const onDecrease=()=>setCount(count-1);
return(
<div>
<h1>{count}</h1>
<div>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
</div>
);
}
export default Counter;
// src/App.tsx
import React from 'react';
import Counter from './Counter';
const App: React.FC=()=>{
return <Counter />;
}
export default App;