🐈오늘 배운 것
✔️프리 프로젝트 팀장이 되었다.
스택 오버플로우를 클론코딩하는 약 2주간의 프리 프로젝트가 시작되었다. 팀장을 하고 싶다고 생각은 했는데, 얼떨결에 하고 싶다고 어필까지 해버렸다. 그래도 어느정도 체계를 갖춘 FE-BE 팀프로젝트는 처음이라 부족한 점이 많지만, 모르면 배우면 되니까 열심히 해보려고 한다.
첫 날에는 자기소개도 하고 팀 빌딩도 하고 서로에 대해 첫 인사를 나누는 시간으로 가졌다. 주 소통 창구는 디스코드로 정했다. 아무래도 주로 사용하는 소통 방식이 디스코드라 편의성을 위해서! 정했던 규칙은 디스코드 상에서 볼 수 있게 채널도 개설하고, 각종 회의 시간에 맞춰 입장할 수 있도록 회의실도 개설하고 등등. 팀원분들과 이야기를 좀 많이 나누었는데 다들 성격도 좋으시고 또 아는 것도 많으셔서 팀원분들께 많이 배울 수 있을 것 같다.
프로젝트 관리 도구를 도입하고 싶은데, 어떤 것이 좋은지 몰라 공부를 해보려고 한다. 흐 미리 좀 할걸 흐흐
✔️함수형 프로그래밍 : map
여전히 100% 이해가 되지 않지만, 언젠간 깨닫는 순간이 있겠지 하며 진행중인 함수형 프로그래밍 강의.
map 함수의 로직을 짜는 내용을 공부했다. 기존 map 함수가 Array.prototype.map 즉 배열의 메소드인 관계로 다른 array-like 이터러블에는 적용할 수 없다는 점이 단점이다. 예를들어 document.querySelectorAll 의 결과로 받아온 NodeList는 정말 배열처럼 생겼지만 map 함수를 적용할 수가 없다.
따라서 함수형 프로그래밍 방식에 따라, 요소를 결정하는 함수와 이터러블을 인자로 받아 새롭게 맵핑된 데이터를 리턴해주는 map 함수 로직을 짤 수 있는데, 아래와 같다.
const map = (f, iter) => {
let res = [];
for (const a of iter) {
res.push(f(a));
}
return res;
};
// 어떤 요소를 mapping 할 것인지 선택하는 보조함수를 전달할 수 있다.
console.log(map(p => p.name, products));
ES6가 등장하면서 웹API 의 데이터 예를 들면 NodeList 라던가... 이런 것들이 이터러블 프로토콜을 따르기 때문에, 위와 같이 이터러블에서도 사용할 수 있는 함수를 정의하면 사용성이 훨씬 좋다고 한다.
이터레이터를 직접 만들어서 map 함수에 전달할 수도 있다. 배열이라던지 set, map 이런 객체가 없어도 제너레이터로 풀어 쓴 이터레이터를 가지고도 아래와 같은 결과물을 산출할 수 있다.
// 제너레이터로 이터러블/이터레이터를 만들어보쟈
function* gen(l) {
for (let i = 1; i <= l; i++) {
yield i;
}
}
// 이렇게 만든 이터레이터를 이터러블로 map에 전달한다.
const iter = gen(5);
console.log(map(el => el, iter));
// [ 1, 2, 3, 4, 5 ]
아래는 map객체 -> mapping 함수 -> 다시 맵 객체 를 만드는 방법이다.
let m = new Map();
m.set('a', 10);
m.set('b', 20);
// map 함수가 요소를 맵핑할 함수와 이터레이터를 받고 있음.
new Map(map(([k, a]) => [k, a * 2], m))
// Map(2) { 'a' => 20, 'b' => 40 }
함수형 프로그래밍에서는 무엇을 할 것인가에 집중한다.
✔️타입스크립트 Generic
`제네릭은 선언 시점이 아니라 생성 시점에 타입을 명시해서, 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법이다`어떤 분이 강의 댓글로 위와 같이 작성하셨는데, 명확한 정의인 것 같아서 인용해보았다.
제네릭을 사용하면 타입스크립트의 타입을 일반화 시킬 수 있다. 예를들어서 함수를 작성하는데 인자로 들어올 값의 타입에 대해서 명확히 모른다면 제네릭을 활용해 볼 수 있다.
// 함수가 받는 인자를 제네릭으로 선언해서 TS에게 유추하도록 함.
function print<V>(a:V[]) {
return a[0]
}
// 배열 안에 아주 여러가지 타입이 있다.
const a = print([1,2,'3',true])
타입 스크립트에서는 any라는 타입이 있는데, 타입이 불명확해서 에러가 발생할 때 타입을 any로 지정하면 에러는 발생되지 않겠지만, 타입에 대한 안정성을 보장받을 수 없다. 왜냐!? 타입이 말그대로 anything이니깐... any 타입을 사용하면 타입 스크립트의 타입 간섭으로부터 벗어날 수 있지만 그 말은 보호받지 못한다는 뜻이므로 가급적 사용을 자제하는 것이 좋다고 한다.
대신 위와 같이 제네릭으로 작성하면, 인자로 받는 타입이 아주 여러가지이거나 명확하지 않아도 타입 체커가 타입을 유추해주기 때문에 안정성이 보장된다.
강의에서는 call signature 에 제네릭을 활용하는 예시가 있었다.
type SuperPrint = {
// 제너릭을 쓴다고 ts에게 알려주는 과정.
<Generic>(arr:Generic[]):void
}
type SuperPrint = {
// 함수가 리턴하는 값의 타입도 제너릭으로 표현할 수 있다.
<T>(arr:T[]):T
// 보이다시피 Generic이든 T이든 이름은 상관없다.
}
const superPrint : SuperPrint = (arr) => {
arr.forEach(el => console.log(el))
}
// 제너릭을 사용했기 때문에 인자로 들어오는 값의 타입을 유추한다.
// 만약 제너릭을 사용하지 않는다면 이러한 타입을 받는 인자에 대해서
// 콜 시그니쳐를 모두 작성해 주었어야 함.
superPrint([1,2,'3','4']);
superPrint([1,2]);
superPrint(['3','4']);
실제로는 call signature를 작성할 일은 많이 없다고 한다. 라이브러리에서 많이 사용하는 방식이기 때문에 알고는 있어야 한다. 또한 대부분의 타입스크립트 타입이 제네릭으로 만들어졌다고 한다.
타입스크립트를 사용? 체험? 해보면서 도대체 이건 왜 이런 문법일까 궁금한 적이 많았는데 너무 어렵게 느껴져서 포기했던 것 같다. 그때 그게 제네릭이라는 것을 알고 보니 이해가 확! 된다.
🐈Feedback
1. 팀장이 되고 나서 팀 회의 발언을 하는데 횡설수설 하는 것 같다는 느낌이 들었다. 약간 팀장 하겠다고 해놓고 자신감이 떨어져서(ㅋㅋㅋ) 그러는 것 같은데, 내가 한 말이지만 모르면 모른다, 알면 안다 명확하게 얘기하고 배우고 나눌 수 있도록 하자.
2. 알고리즘을 너~무 대충 풀고 있다. 강의에 답안이 있어서 그런지 조금만 안풀리면 강의를 보고싶다는 유혹에 휩싸인다. 고민의 과정이 실력이 되는 것이니까 소홀히 하지 말자.
🐈To Do
1. 협업 플로우 개념잡기
2. 스터디 준비, 루틴 정비
'TIL' 카테고리의 다른 글
[TIL] 2022-1212 : 이력서 작성을 위한 에피소드 정리 / 뽑히는 개발자의 포트폴리오 라이브세션 / 모락모락 프로젝트 코멘트 리팩토링 (3) | 2022.12.12 |
---|---|
[TIL] 2022-1111 : UI 프로토타입 작업 / 타입스크립트 공부 (1) | 2022.11.12 |
[TIL] 2022-1019 (티스토리 복구 경축!) (0) | 2022.10.19 |
[TIL] 2022-1013 (0) | 2022.10.13 |
[TIL] 2022-1012 (0) | 2022.10.12 |