이펙티브 타입스크립트 10~20 아이템 중간고사

공효은·2023년 11월 2일
0

typescript

목록 보기
6/8

1. 잉여 속성 체크에 대한 설명으로 틀린것을 고르시오!

  1. 타입이 명시된 변수에 객체 리터럴을 할당할 때 타입스크립트는 해당 타입의 속성이 있는지, 그리고 '그 외의 속성은 없는지' 확인한다.
  2. 객체 리터럴을 변수에 할당하거나 함수에 매개변수로 전달할 때 잉여속성 체크가 수행된다.
  3. 잉여 속성 체크를 이용하면 기본적으로 타입 시스템의 구조적 본질을 해치지 않으면서 객체 리터럴에 알 수 없는 속성을 허용하지 않는다.
  4. 잉여속성 체크는 타입 단언문을 사용할 때에 적용된다.
  5. 잉여 속성 체크에는 한계가 있다. 임시 변수를 도입하면 잉여 속성 체크를 건너뛸 수 있다.

답: 4 잉여 속성 체크는 타입 단언문을 사용할 때에 적용되지 않는다.

interface Options {
 title: string;
 darkMode?: boolean;
}

const o = {darkmode: true, title: 'Ski Free'} as Options; // 정상 잉여속성 체크 적용되지 않음

2. 다음 결과 타입을 맞추시오!

interface SaveAction {
  type: 'save';
  //...
}
interface LoadAction {
  type: 'load';
  //...
}
type Ation = SaveAction | LoadAction;

1) Action 유니온을 인뎅싱 하면 타입 반복 없이 ActionType을 정의할 수 있다.

type ActionType = Action['type'];

정답: "save" | "load"

2) Pick을 사용하여 type 속성을 가져옴

type ActionRec = Pick<Action, 'type'>; 

정답: type 속성을 가지는 인터페이스 {type: "save" | "load"}

3. 함수에서 매개변수로 매핑할 수 있는 값을 제한하기 위해 타입 시스템을 사용하는 것처럼 제너릭 타입에서 매개변수를 제한할 수 있는 방법은 무엇일까?

정답: extends
extends를 이용하면 제너릭 매개변수가 특정 타입을 확장한다고 선언할 수 있다.

앞에 나온 Pick의 정의는 extends를 사용해서 완성할 수 있다. 타입 체커를 통해 기존 예제를 실행해 보면 오류가 발생한다.

type Pick<T,K> = {
  [k in K]: T[k]
  // ~ 'K' 타입은 'string | number | symbol' 타입에 할당할 수 없습니다.
}

K는 T 타입과 무관하고 범위가 너무 넓다 K는 인덱스로 사용될 수 있는 string | number | symbol 이 되어야 하며 실제로는 범위를 조금 더 좁힐 수 있다. K는 실제로 T의 키의 부분 집합, 즉 keyof T가 되어야한다.

타입이 값의 집합이라는 관점에서 생각하면 extends를 '확장'이 아니라 '부분 집합' 이라는 걸 이해하는 데 도움이 된다.

type Pick<T, K extends keyof T> = {
  [k in K] : T[k]
}

4. keyof 연산자에 대해서 설명하시오.

정답: keyof 연산자는 객체 타입에서 객체의 키 값들을 숫자나 문자열 리터럴 유니언을 생성한다.

interface Options {
  width: number;
  height: number;
  color: string;
  label:string;
}

type OptionsKeys = keyof Otions;
//타입이 "width" | "height" | "color" | "label"

5. '인덱스 시그니처' 에 대한 설명으로 틀린것을 고르시오.

type Rocket = {[property: string]: string};
  1. 키의 이름은 키의 위치만 표시하는 용도이다. 타입 체커에서는 사용하지 않기 때문에 무시할 수 있는 참고 정보이다.
  2. 키의 타입은 string 또는 number 또는 symbol의 조합이어야 하지만, 보통은 string을 사용한다.
  3. 값의 타입은 일반적으로 string 만 사용가능하다.
  4. 특정 키가 필요하지 않다. {}도 유효한 Rocket 타입이다.
  5. 키마다 다른 타입을 가질 수 없다.
  6. 인덱스 시그니처는 동적 데이터를 표현할때 사용한다.

답: 3번 값의 타입은 어떤 것이든 될 수 있다.

6. 매개 변수를 reanonly 선언하면 일어날 일로 틀린것을 고르시오

  1. 타입스크립트는 매개변수가 함수내에서 변경이 일어나는지 체크한다.
  2. 호출하는 쪽에서는 함수가 매개변수를 변경하지 않는다는 보장을 받는다.
  3. readonly는 깊게 동작한다.
  4. 자바스크립트에서는(타입스크립트에서도 마찬가지) 명시적으로 언급하지 않는 한, 함수가 매개변수를 변경하지 않는다고 가정한다. 명시적인 방법을 사용하는 것이 컴파일러와 사람에게 모두 좋다.
  5. 인덱스 시그니처에 readonly를 사용하면 객체의 속성이 변경되는 것을 방지할 수 있다.
    정답:3 readonly는 얕게 동작한다. ts-essentials에 있는 DeepReadonly 제너릭을 사용하면 된다.
interface Outer {
  inner: {
    x: number;
  }
}
const o: Readonly<Outer> = { inner: { x: 0 }};
o.inner = { x: 1 };
// 읽기 전용 속성이기 때문에 'inner'에 할당할 수 없습니다.
o.inner.x = 1; // 정상
    

7. 타입과 인터페이스에 대한 설명으로 틀린것을 고르시오!

1.타입 별칭과 인터페이스는 모두 제너릭이 가능하다.
2. 인터페이스는 타입을 확장할 수 있으며 타입은 인터페이스를 확장할 수 있다.
3. 인터페이스는 유니온 타입 같은 복잡한 타입도 확장할 수 있다.
4. 인터페이스는 타입에 없는 몇가지 기능이 있다. 그중 하나가 바로 보강 이다.

정답: 3 인터페이스는 유니온 타입 같은 복잡한 타입을 확장 할 수 없다. 타입과 &를 사용해야
한다.

type Input = {...}
type Output = {...}
type NamedVariable = (Input | Output) & {name: string};

인터페이스는 이런거 없음

profile
잼나게 코딩하면서 살고 싶어요 ^O^/

0개의 댓글