정말 핫한 인프콘을 다녀와서 느낀 점?이라고 하고 주절주절 써보려 한다.
추첨을 통해 참석을 할 수 있었는데 운이 좋게 당첨되어서 구경 가봤다.
딱히 기대하지 않고 있었는데 막상 당첨되니까 신기하고 같은 팀에서 나 포함 2명만 당첨되어 다 같이 가지 못해 아쉽긴 했다.
10시를 넘어서 도착해 건물 입구까지만 해도 사람이 별로 없었는데 막상 홀에 들어가니 엄청 많았다.
역시 컨퍼런스를 오면 다른 개발자들의 열정을 느낄 수 있어서 동기부여에 도움이 되는 것 같다.
이렇게나 많은 발표가 있었지만 오전에 3개를 참석하고 오후에는 선물 받으러 부스를 돌아다녔다 ㅋㅋㅋ 선물은 못 참지
내가 들었던 발표는
1. 타입스크립트는 왜 그럴까? (집합으로 이해하는 타입스크립트)
2. 2곳 중 1곳은 무조건 합격하는 개발자 이력서 만들기
3. 왜 내가 만든 서비스는 아무도 안 쓰지? (개발자가 알아두면 좋은 사이드 프로젝트 제작 팁)
제일 아쉬웠던 것은 선물에 눈이 멀어 늦게 두번째 발표장에 늦게 도착해 자리가 없어서 착석하지도 못하고 기록도 하지 못했다.
역시 이력서 관련 발표여서 내가 참석한 발표 중 참석자가 가장 많았던 것 같다.
오늘 듣지 못한 발표들은 유튜브로 공개되면 한번 들어봐야겠다. (제발 꼭 들어야지...)
기록했던 나머지 2개의 발표에 대해서 정리해두려고 한다.
타입스크립트는 왜 그럴까? (집합으로 이해하는 타입스크립트) - 이정환(지식공유자)
1. 타입을 집합으로 이해하기
예를 들어 강아지와 고양이는 동물이라는 집합으로 묶을 수 있다.
동물 = 슈퍼타입, 강아지와 고양이 = 서브타입이라고 생각하면 된다.
// number 리터럴 타입은 단 하나의 숫자값을 포함하는 아주 작은 집합이다.
let num:20 = 20;
let num:20 = 30; // 20만 할당 할 수 있어 error가 발생한다.
// number 타입은 모든 숫자를 포함하는 큰 집합이다.
let num:number = 20;
let num:number = 30;
// number 리터럴 타입은 number 타입의 부분 집합이다.
// number 타입은 슈퍼 타입(부모), number 리터럴 타입은 서브 타입(자식)이다.
2. 타입 호환성 이해하기
타입 호환성은 타입 간의 슈퍼 서브 관계를 기준으로 판단된다.
업 캐스팅과 다운 캐스팅라는게 존재한다.
업 캐스팅
자식 → 부모 방향으로 형변환
다운 캐스팅
부모 → 자식 방향으로 형변환
강아지는 동물의 부분 집합이지만 동물은 강아지의 부분 집합이 아니라고 생각하면 쉬울 것 같다.
동물 중에서 강아지만 존재하는 게 아니기 때문에 동물은 강아지의 부분 집합이 성립하지 않는다.
let a:number = -12;
let b:30 = 30;
a = b; // o number 타입에 number 리터럴 타입은 할당 가능하다. (업캐스팅)
b = a; // x number 리터럴 타입에 number 타입은 할당 불가능하다. (다운캐스팅)
3. 타입 계층도 살펴보기
발표에선 타입 중 any, unknown, never 타입에 대해서 알려주었다. 마찬가지로 집합의 관점으로 이해해 보자
unknown
unknown은 모든 타입의 슈퍼 타입이다.
모든 집합을 포함하는 가장 큰 집합이며 전체집합으로 비교할 수 있다.
어떠한 값이든 할당 가능하다.
어떤 타입의 변수에도 저장할 수 없다.(다운캐스팅에 해당한다)
언제 사용할까?
1. 현재 정확한 타입을 알기 어려울 때
현재 정확한 타입을 알기 어려울 때는 any 타입을 사용하는 것보다unknown 타입을 사용하는 것이 더 좋다고 했는데 어디서 본 건지 기억이 안 난다...
2. 타입 좁히기와 함께 값을 유연하게 사용 가능
// color라는 인수를 사용하지만 어떤 타입인지 모를 때
const colorName = (color: unknown) => {
if (typeof color === "string") {
// 타입 좁히기를 사용해 타입을 보장하여 사용 할 수 있다.
}
}
never
unknown과 정반대 타입이다.
타입 계층도의 최하단이며 모든 타입의 서브타입이다.
집합의 관점에서 모든 집합의 부분 집합(∅ 공집합)
모든 타입의 변수에도 저장 가능하다.
어떤 타입의 값도 저장할 수 없다. (다운 캐스팅에 해당한다)
언제 사용할까?
1. 호출되지 않아야 하는 함수를 만들 때
// 이런 경우는 언제 쓰는지 잘모르겠다 :(
const fn = (x:never) {}
fn() // 에러 인수x에 아무 값도 주지 않아서
fn('foo') // 에러 string 타입은 never 타입에 할당 할 수 없다.
fn(1) // 에러 number 타입은 never 타입에 할당 할 수 없다.
2. switch의 완전성을 보장하기 위해 (모든 케이스를 처리하지 않는 것이 완정성이 보장되지 않은 switch문이다)
const errorFn = (x: never) => {
throw new Error("color error");
}
const color = (color: "red" | "blue" | "green") => {
switch (color) {
case "red":
return "red color";
case "blue":
return "blue color";
default:
return errorFn(color); // green의 경우 에러를 발생한다.
}
}
any
타입 계층도를 무시하고 자기 맘대로 동작한다. 물론 타입 검사하지 않는다.
any도 하지 못하는 것이 있다.
never타입에는 any타입을 할당하지 못한다. never타입은 공집합이니까 값을 할당하는 것이 불가능하기 때문이다.
언제 사용할까? (그냥 안 쓰는 게 좋을 것 같다. 물론 내 생각)
1. 불가능한 타입 단언을 가능케 할 수 있다.
let str: string = 10 as string // 불가능한 일이다.
let str2: string = 10 as any as string; // 가능하다. 10을 any타입으로 변환하고 any타입을 다시 string으로 변환하기 때문이다.
중간에 타입에 대한 간단한 퀴즈를 내주셨다. 다들 쉽게 맞췄을 것 같다.
type A = never & string // never 타입
type B = never | string // string 타입
type C = unknown & string // string 타입
type D = unknown | string // unknown 타입
4. 객체 타입과 집합
프로퍼티를 기준으로 타입을 정의한다.
type Person = { name: string; }
name 프로퍼티를 가진 모든 집합이 Person 타입이 가능하다.
type A = { x: string; }
type B = {
x: string;
y: string;
z: string;
}
A타입을 부분집합으로 성립하려면 x 프로퍼티만 가지면 되지만
B타입을 부분집합으로 성립하려면 x, y, z 프로퍼티를 모두 가져야 하기 때문에
프로퍼티를 적게 가질수록 집합이 커진다.
5. 대수 타입과 집합
둘 이상의 타입을 합쳐 만든 타입이며 유니온과 인터섹션이 있다.
유니온
type Person = { name: string; };
type Student = { school: string; };
type Union = Person | Student;
// type Union 경우
// 1. Person 타입에만 포함되는 값
// 2. Student 타입에만 포함되는 값
// 3. Person, Student 타입에 모두 속하는 값
인터섹션
type Person = { name: string; };
type Student = { school: string; };
type Intersection = Person & Student;
// type Intersection 경우
// 1. Person, Student 타입 모두 속하는 값
마무리
회사에서 타입스크립트를 도입한 지 몇 개월이 지난 것 같다.
나름 타입스크립트도 적응된 것 같고
요즘엔 타입 좁히기에 맛들려서 타이트하게 타입을 좁히면 그것만큼 재밌는 것이 없다.
가끔 함수의 인수에서 union타입의 경우 에러 해결하는데 애를 먹었는데 들었던 발표를 생각하며 다시 천천히 수정해 봐야겠다.
이미 알고 있는 것이라고 생각했는데 집합의 관점에서 생각해보려고 하지 않은 것 같다.
발표자께서 인프런에서 하시는 강의 50% 할인 쿠폰도 주셨다.
8월 18일까지 사용가능하니 사용하실 분은 얼른 사용하면 좋을 듯합니다.
사진 찍어가라고 해서 공유해도 될 것으로 판단해서 올립니다!!
왜 내가 만든 서비스는 아무도 안 쓰지? (개발자가 알아두면 좋은 사이드 프로젝트 제작 팁) - 이동훈(omelet)
1. 좋은 문제를 찾고, 이해하고, 해결하기
작품과 상품의 차이를 생각해 보자.
작품은 작가의 생각으로 만들어지며 나에게서 출발한다.
상품은 시장의 니즈로 만들어지며 사용자로부터 출발한다.
많은 사이드 프로젝트가 솔루션을 먼저 정의하고 고객을 끼워 맞추는 경우가 많다.
내가 만들고 싶은 서비스를 만들고 있었기 때문에 실패의 원인이 된다. (개발자로서 기술을 공부하기 위한 경우는 제외)
사이드 프로젝트는 좋은 문제를 찾고, 이해하고, 해결하는 것이다.
사용자가 진짜로 필요한 문제를 찾고 해결해 보는 것을 중심으로 생각해 보자.
좋은 문제를 찾는 방법
1. 반문하기
주변에 당연하다고 여기는 것을 당연하지 않게 반문하기
2. 관찰하기
기존의 프로세스를 관찰한다.
3. 펼쳐보기
어떤 것을 개선할 수 있는지 찾아보기, 시장의 크기를 볼 수 있으면 더욱 좋다.
만약 좋은 문제를 찾기 어렵다면 나 자신이 고객인 문제를 찾아보자. 그럼 사용고객이 최소한 1명은 보장이 된다.
2. 가능한 짧은 시간 내에 완성하기
사이드 프로젝트는 돈이 아닌 성장에 즐거움을 가져가기 때문에 동기부여를 지속적으로 얻어야지 사이드 프로젝트의 완성에 도움이 된다.
만약 완성하지 못한다면 그것은 시간을 허비한 것과 다름이 없다. 위에서 말했던 것처럼 개발적인 기술을 습득하게 되었다면 그건 또 나름의 성과라고 생각한다.
사이드 프로젝트를 완성하기 어려운 이유
1. 초기 기획과 달리 늘어나는 기능
2. 처음부터 완벽하게 개발하려는 생각
가능한 짧은 기간 내에 제작하는 것이 중요하다. (3개월 또는 6개월)
오래 개발한다고 해서 완성도 있는 서비스가 되는 것이 아니다. 일단 출시하고 추가적인 피드백을 받으며 발전하면 된다.
핵심 기능 하나에 집중하기
3. 만든 여정을 기록하기
대부분의 사이드 프로젝트는 실패하며 지속되기 어렵다.
이렇게 끝이 나면 개발자로서 성장하는 것 외에는 아무것도 남지 않는다. 제 3자가 보았을 때는 공감하기 어렵다.
어떤 생각으로 사이드 프로젝트를 했는지 어떻게 해결했는지 알 수 없다.
블로그 또는 깃헙등 만든 여정을 기록해야 된다.
1. 어떤 문제를 어떻게 해결했는지
2. 어떤 기술스택을 왜 사용했는지
3. 어떤 결과가 있었고 얻은 점은 무엇인지
중요한 것은 꺾이지 않는 도전이며, 사이드 프로젝트에서 가장 중요한 것은 시도, 도전이다.
작은 시도, 작은 실패, 작은 성공이라고 말씀하셨다.
작은 시도로 도전에 대한 부담감을 줄이고
작은 실패를 하기도 하지만
비록 작은 성공이지만 작은 성공이 원동력이 돼 큰 성공을 얻을 수 있다고 말씀하시는 것 같다.
마무리
6개월째 제작 중인 사이드 프로젝트가 있어서 이번 발표가 정말 궁금했다.
발표에서 말씀하신 실패의 경우에 딱 맞아떨어지는 나의 사이드 프로젝트였다.
완벽하게 하려고 출시도 계속 늦어지고 만든 여정도 기록하지 않았으니 정말 실패의 모든 경우를 다 갖추어버렸다.
현재 발견한 에러까지 해결하고 회고록도 작성하고 사람들에게 공개하도록 해야 되겠다. 빨리 출시해서 뚜드려 맞는 게 속 편할 것 같다.
실패한 사이드 프로젝트가 되지 않도록 하고 싶지만 사용자 관점에서 메리트를 크게 느끼지 못할 것 같아 걱정이 많다.
다음번 사이드 프로젝트를 할 때는 발표에서 알려 준 것처럼 작품이 아닌 상품의 관점에서 제작을 해보고 싶다.
'컨퍼런스' 카테고리의 다른 글
서비스에서 접근성이 왜 필요할까? (0) | 2023.11.13 |
---|