Jieunny의 블로그
TypeScript 본문
- TypeScript : 자바스크립트에 타입을 부여한 언어로 자바스크립트의 확장된 언어라고 볼 수 있다.
- '정적타입을 지원한다' - 변수나 데이터의 종류를 명확히 지정
- 정적 타이핑
-
function sum(a: number, b: number) { //타입을 미리 설정할 수 있음 return a + b; }
- const message : string = 'hello world' //해당 상수 값이 문자열이라는 것을 명시 -> 해당 값을 숫자로 설정해버리면 오류가 나타난다.
- 우리가 사전에 지정한 타입이 아닌 값이 설정될 때 바로 에러를 발생시킨다 -> 에러가 나타났을 땐 컴파일이 되지 않는다.
-
function sum(x: number, y: number): number { //x,y 값이 number, sum 결과 값도 number 라는 뜻 return x + y; } sum(1, 2); //에러안남 sum(); //에러남
- interface
- 클래스에서 interface를 implements 하기
- interface : 클래스 또는 객체를 위한 타입을 지정할 때 사용되는 문법
- interface 를 사용하여 클래스가 가지고 있어야 할 요구사항 설정
- 클래스 선언 시 implements 를 사용하여 해당 클래스가 특정 interface 를 구현한다는 것을 명시
-
interface Shape { getArea(): number; // Shape interface 에는 getArea 라는 함수가 꼭 있어야 하며 해당 함수의 반환값은 숫자 } class Circle implements Shape { // `implements` 키워드를 사용하여 해당 클래스가 Shape interface 의 조건을 충족하겠다는 것을 명시 constructor(public radius: number) { this.radius = radius; }
- 일반 객체를 interface 로 타입 설정하기
-
interface Person { name: string; age?: number; // 물음표가 들어갔다는 것은, 설정을 해도 되고 안해도 되는 값이라는 것을 의미 } interface Developer extends Person { // Person interface를 상속받음 skills: string[]; } const person: Person = { name: '김사람', age: 20 };
-
- Type Alias 사용하기
- 특정 타입에 별칭을 붙이는 용도
- 객체, 배열 어떤 타입이던 별칭을 지어줄 수 있다.
-
type People = Person[]; //Person[]을 앞으로 People 이라는 타입으로 사용 할 수 있다
- 함수에서 Generics 사용하기
- Generics : 여러 종류의 타입에 대하여 호환을 맞춰야 하는 상황에서 사용하는 문법.
- 어떤 타입이 올 지 모르는 상황에서 사용할 때 타입이 깨지지 않게 함.
-
function wrap<T>(param: T) { return { param //param: number; 와 같음 } } const wrapped = wrap(10);
- <T> 처럼 '<>' 안에 타입의 이름을 넣어서 사용
- interface에서 Generics 사용하기
-
interface Items<T> { list: T[]; } const items: Items<string> = { list: ['a', 'b', 'c'] };
- Items<string> 라는 타입을 사용하게 되면, Items 를 지니고 있는 객체 list 배열은 string[] 타입을 지니고 있게 된다.
-
- Type alias 에서 Generics 사용하기
-
type Items<T> = { list: T[]; }; const items: Items<string> = { list: ['a', 'b', 'c'] };
-
- 클래스에서 interface를 implements 하기
- Map을 사용하는 방법
- Map: Key를 이용하여 Value를 저장하는 방식의 자료구조
- Key는 중복될 수 없고 중복될 경우, 가장 마지막 value가 저장된다.
- 선언
-
const map = new Map(); const mapWithType = new Map<string, any[]>();
-
- 데이터 저장
- set(key, value) 를 이용해 key와 value를 저장한다.
-
const map = new Map<string, string[]>(); map.set('key1', ['value1', 'value2']); map.set('key2', ['value1', 'value2', 'value3']); map.set('key3', ['value1', 'value2', 'value3', 'value4']); map.set('key2', ['value1']); // key가 중복될 경우, 가장 마지막 value가 저장되기 때문에 특정 key의 value를 업데이트 할 때 사용된다.
- 데이터 삭제
- delete(key) 사용
-
map.delete('key2'); // 가능 map.delete('key4'); // key 값이 key4인 데이터가 없으므로 불가능
- clear() 사용해서 모든 데이터 삭제 가능
- 데이터 조회
- get(key) 사용
-
map.get('key1'); // value1, value2 map.get('key4'); // undefined
- 데이터 존재 여부 확인
- has(key) 사용
-
map.has('key1'); // true map.has('key4'); // false
- key or value 값을 리스트 형태로 구하기
- keys(), values() 사용
-
const mapKeys = map.keys(); for (const key of mapKeys) { ${key} } // key1, key2, key3
- 반복문
- for ... of
-
const map = new Map<string, string[]>(); map.set('keyOne', ['value1', 'value2']); map.set('keyTwo', ['value1', 'value2', 'value3']); map.set('keyThree', ['value1', 'value2', 'valu3', 'value4']); for (const [key, values] of map) { console.log(`KEY: ${key}, VALUE: ${values}`); } // KEY: keyOne, VALUE: value1,value2 // KEY: keyTwo, VALUE: value1,value2,value3 // KEY: keyThree, VALUE: value1,value2,valu3,value4
- forEach
- value, key, Object 순서
- key, value의 위치에 주의해야한다.
-
const map = new Map<string, string[]>(); map.set('keyOne', ['value1', 'value2']); map.set('keyTwo', ['value1', 'value2', 'value3']); map.set('keyThree', ['value1', 'value2', 'valu3', 'value4']); // obj === map map.forEach((values, key, obj) => { console.log(`KEY: ${key}, VALUE: ${values}`); }); // KEY: keyOne, VALUE: value1,value2 // KEY: keyTwo, VALUE: value1,value2,value3 // KEY: keyThree, VALUE: value1,value2,valu3,value4
- Type Alias vs Interface
- 둘다 비슷한 방식으로 이름을 지어줄 수 있다.
-
//interface interface Human { name: string; age: number; } const jieun: Human = { name: '김지은', age: 23 }; //Type Alias type Human = { name: string; age: number; }; const jieun: Human = { name: '남현욱', age: 20, };
- Interface는 선언 병합이 가능하지만, Type Alias 는 불가능 하다.
- 선언 병합 : 동일한 이름으로 여러 번 선언해도 컴파일 시점에 합칠 수 있다.
- TypeScript로 리액트 Hooks 사용하기
- 1) useState
- 제네릭 <number>을 통해 해당 state가 어떤 타입을 가지고 있는지 설정한다.
-
import React, { useState } from 'react'; function Counter(){ const [count, setCount] = useState<number>(0); // count 값이 number 라는 것을 명시 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> ); }
- 제네릭을 사용하지 않아도 자동으로 유추하는데 왜 사용하나?
- 1) state가 null일 수도 있고 아닐수도 있을때 유용하다.
-
type Information = { name: string; description: string }; const [info, setInformation] = useState<Information | null>(null);
- 2) state의 타입이 까다로운 구조를 가진 객체이거나 배열일 때는 명시하는 것이 좋다.
-
type Todo = { id: number; text: string; done: boolean }; const [todos, setTodos] = useState<Todo[]>([]);
- useRef : 인자로 넘어온 초깃값을 useRef 객체의 .current 프로퍼티에 저장한다. 이 current 속성은 값을 변경해도 상태를 변경할 때 처럼 React 컴포넌트가 다시 렌더링 되지 않는다. React 컴포넌트가 다시 렌더링될 때도 마찬가지로 current 속성의 값이 유실되지 않는다.
- 정의 3개
- 1. useRef<T>(initialValue: T): MutableRefObject<T>
- 인자의 타입과 제네릭의 타입이 T로 일치하는 경우, MutableRefObject<T>를 반환한다.
- MutableRefObject<T>의 경우 current 프로퍼티 그 자체를 직접 변경할 수 있다.
- 2. useRef<T>(initialValue: T|null): RefObject<T>
- 인자의 타입이 null을 허용하는 경우, RefObject<T>를 반환한다.
- RefObject<T>는 current 프로퍼티를 직접 수정할 수 없다.
- 3. useRef<T = undefined>(): MutableRefObject<T | undefined>
- 제네릭의 타입이 undefined인 경우 MutableRefObject<T | undefined>를 반환한다.
-
import React, { useRef } from 'react'; const App = () => { const localVarRef = useRef<number>(0); // useRef를 로컬변수로 사용하는 경우 const handleButtonClick = () => { if (localVarRef.current) { localVarRef.current += 1; // 버튼을 클릭할 때 마다 localValRef.current 값이 1씩 증가 console.log(localVarRef.current); } }; // .current를 직접 수정할 수 있는 이유: useRef에 제네릭타입과 동일한 타입의 초기 인자를 줬으므로 1번 케이스. // 때문에 localVarRef 는 MutableRefObject<number> 타입이고, .current를 직접 수정 가능, 로컬 변수처럼 사용할 수 있다. return ( <div className="App"> <button onClick={handleButtonClick}>+1</button> <div> ); }; export default App;
- 만약 useRef에 인자를 null로 초기화 했다면?
-
... const localValRef = useRef<number>(null); // null로 초기화 // null로 초기화하는 건 2번 경우, .current가 readonly인 RefObject를 반환하므로 직접 수정 못함. const handleButtonClick = () => { localValRef.current += 1; console.log(localVarRef.current); }; ... // current 프로퍼티만 읽기 전용이고 current 프로퍼티의 하위 프로퍼티인 value는 여전히 수정 가능하다. // localValRef.current.value 는 수정 가능하다.
- 로컬 변수 용도로 useRef를 사용하는 경우, MutableRefObject<T>를 활용
- DOM을 직접 조작하기 위해 프로퍼티로 useRef를 사용하는 경우, RefObject<T>를 사용해야 하므로 초깃값을 null로 해주자.
- 1. useRef<T>(initialValue: T): MutableRefObject<T>
- 1) useState
'React > etc' 카테고리의 다른 글
CSS 속성 선언 순서 (0) | 2021.12.26 |
---|---|
CRA 없이 React 환경 구축 (0) | 2021.12.19 |
styled-component (0) | 2021.12.17 |
<usum> main.css (에어비엔비 convention) (0) | 2021.12.17 |
SASS (0) | 2021.12.17 |