woowacourse-study / 2022-thanks-giving-effective-typescript

🍂추석 연휴 집중🍂 이펙티브 타입스크립트를 읽는 모임 (✌️완주완료✌️)
6 stars 0 forks source link

2022.09.09 #6

Closed moonheekim0118 closed 1 year ago

moonheekim0118 commented 1 year ago

더도말고 덜도말고 타입스크립트만 같아라 타스와 함께 해피추석 스딸뜨

soyi47 commented 1 year ago

해피 땡스기빙 이펙티브 타입스크립트 본격 출발!! 🚗🚗🚗

아이템 19. 추론 가능한 타입을 사용해 장황한 코드 방지하기

아이템 20. 다른 타입에는 다른 변수 사용하기

아이템 21. 타입 넓히기

아이템 22. 타입 좁히기

아이템 23. 한꺼번에 객체 생성하기

아이템 24. 일관성 있는 별칭 사용하기

prefer2 commented 1 year ago

🌕 타입스크립트와 함께하는 풍요로운 한가위 되세요~ 🌕

한꺼번에 객체 생성하기

const pt = {};
pt.x = 3; // {} 형식에 'x' 속성이 없습니다

변수의 값은 변경될 수 있지만 타입은 일반적으로 변경되지 않는다. 따라서 객체를 생성할 때는 속성을 하나씩 추가하는 것ㅂ도나는 여러 속성을 포함해서 한꺼번에 생성해야 타입 추론에 유리하다.

spread operator(…) 사용하기

interface Point {
  x: number,
  y: number
}

const pt0 = {};
const pt1 = {...pt0, x: 3};
const pt:Point = {...pt1, y:4};

작은 객체들을 조합해서 큰 객체를 만들 경우에도 여러 단계를 거치는 것(Object.assign과 같은 메서드를 사용해서)은 좋지 않다. spread operator를 사용하면 큰 객체를 한번에 만들 수 있다.

전개 연산자를 사용하면 타입 걱정 없이 필드 단위로 객체를 생성할 수 있다. → 원하는 객체의 형식을 class처럼 지정해놓고 이를 전개 연산자로 풀어서 합치는 방법을 말하는듯?

조건부 속성 사용하기

declare let showAge: boolean;
const nameEmoji = {name: 'dory', emoji: '🐠' };

const aboutDory = {
  ...nameEmoji,
  ...(showAge ? { birth: 1998, age: 25 } : {})  
}

안전한 방식으로 조건부 속성을 추가하려면 null또는 {} 객체 전개를 사용하면 된다.

declare const aboutDory: {
    birth: number;
    age: number;
    name: string;
    emoji: string;
} | {
    name: string;
    emoji: string;
};
declare const aboutDory: {
    birth: number;
    age: number;
    name: string;
    emoji: string;
} | {
    name: string;
    emoji: string;
};

전개 연산자로 한꺼번에 여러 속성을 추가할 수도 있다. 이 경우 조건문의 객체가 유니온 타입으로 추론된다. 이를 통해 유니온을 사용하는 것이 가능한 값의 집합을 더 정확하게 표현할 수 있음을 알 수 있다. (🚨주의🚨 v4.0.5까지만 이렇게 변환된다. 이후 버전부터는 아래처럼 선택적 필드로 변환된다. 이제는 아래와 같이만 쓰이니 주의하자!!!!)

declare const aboutDory: {
    birth?: number | undefined;
    age?: number | undefined;
    name: string;
    emoji: string;
};

비동기 코드에는 콜백 대신 async 함수 사용하기

타입스크립트는 런타임에 관계 없이 async/await를 사용할 수 있다.

콜백보다는 Promise가 타입을 추론하기 쉽다.

Promsie.race도 타입 추론과 잘 맞는다. 타입 구문 없어도 반환 타입이 Promise로 추론된다. Promise.race의 반환 타입은 입력 타입들의 유니온이고, race의 특성상 Promise<Response | never>가 된다. never는 공집합으로 유니온에 아무런 효과가 없어 Promise로 간단해진다.

Promise보다 async/await을 사용

async 함수는 항상 프로미스를 반환하도록 강제한다.

const getNumber = async () => 42; // Promise<number>

사실상 즉시 사용 가능한 값이지만 async를 사용하면 항상 비동기로 실행된다. 함수를 사용할때 동기와 비동기가 섞여서는 안되는데 async는 코드 작성시 이를 도와준다. 콜백이나 프로미스를 사용하면 실수로 일부만 동기인 코드를 작성할 수 있지만, async를 사용하면 항상 비동기 코드를 작성하게 된다.

liswktjs commented 1 year ago

다들 즐추~~

맵핑된 타입을 사용하여 값을 동기화하기

const REQUIRES_UPDATE: {[k in keyof ScatterProps] : boolean} = {
    xs: true,
    ys: true,
    xRange: true,
    yRange: true,
    color: true,
    onClick: false,
};

function shouldUpdate(
    oldProps: ScatterProps,
    newProps: ScatterProps 
){
    let k : keyof ScatterProps;
    for (k in oldProps){
        if (oldProps[k] !== newProps[k] && REQUIRES_UPDATE[k]){
            return true;
        }
    }
}

추론 가능한 타입을 사용해 장황한 코드 방지하기

다른 타입에는 다른 변수 사용하기

타입 넓히기

타입 좁히기

moonheekim0118 commented 1 year ago

한꺼번에 객체 생성하기

조건부로 객체에 속성 추가하기

function addOptional<T extends object, U extends ojbect>(
    a: T, b: U | null
): T & Partial<U>{
   return { ...a, ...b };
}

const pharaoh = addOptional (
    nameTItle,
    hasDates ? {start:  -2589, end: -2566} : null
)

일관성 있는 별칭 사용하기

const state = { location : 1 };
const loc = state.location; // 요게 별칭!

비동기 코드에는 콜백 대신 async 함수 사용하기

콜백보다는 프로미스 사용하기

프로미스를 생성하기 보다 async/await 생성하기

타입 추론에 문맥이 어떻게 사용되는지 이해하기

type Language = 'JavaScript' | 'TypeScript';

function setLanguage(language: Language){}

setLanguage('JavaScript'); // 정상

let language = 'JavaScript'; setLanguage(language); // Error // 'string' 형식의 인수는 'Language' 형식의 매개변수에 할당 될 수 없습니다.

- why?
- 타입스크립트는 할당 시점에 타입을 추론한다.
- 따라서 string 으로 추론된것...

### 해결방법
1. 타입선언하기
```ts
let language:Language = 'JavaScript';
  1. 상수로 만들기
const language = 'JavaScript';

튜플 사용


function panTo(where:[number,number]){}

panTo([10,20]); // 정상

conset loc = [10,20];
panTo(loc);
// number[] 형식의 인수는
// [number,number] 형식의 매개변수에 할당될 수 없습니다.

해결하기 as const


function panTo(where:[number,number]){}

conset loc = [10,20] as const;
panTo(loc);
// Error: readonly[10,20] 형식은 
// 변경가능한 형식 [number,number] 에 할당 할 수 없습니다.