TypeScript - Effective TypeScript 1.1 & 1,2

이소라·2022년 8월 6일
0

TypeScript

목록 보기
11/28

1. TypeScript 이해하기

1.1 JavaScript와 TypeScript의 관계

  • TypeScript는 JavaScript의 상위 집합임

    • JavaScript 프로그램에 문법 오류가 없다면, 유효한 TypeScript 프로그램임
    • JavaScript 프로그램에 이슈가 존재한다면, 문법 오류가 아니더라도 타입 체커에게 지적당할 수 있음
      • 문법의 유효성과 동작의 이슈는 독립적임
    • JavaScript 코드를 TypeScript 코드로 변환할 수 있음
      • 기존에 존재하는 JavaScript 코드를 TypeScript로 Migration할 수 있음
      • 기존의 코드를 유지하면서 일부분만 TypeScript를 적용 가능함
  • 모든 TypeScript는 JavaScript가 아님

    • TypeScript에는 타입을 명시하는 추가적인 문법이 존재함
// TypeScript
function greet(who: string) {
  console.log('Hello, who);
}
// JavaScript
// Syntax Error: Unexpected token :
function greet(who: string) {
  console.log('Hello, who);
}
  • TypeScript는 정적 타입 시스템임

    • 타입 시스템의 목표 중 하나는 런타임에 오류를 발생시킬 코드를 미리 찾아내는 것임
  • TypeScript는 타입 구문 없이도 오류를 잡을 수 있지만, 타입 구문을 추가하면 훨씬 더 많은 오류를 잡을 수 있음

    • 코드의 의도가 무엇인지 타입 구문을 통해 알려줄 수 있음
// bad
const states = [
  {name: 's', froit: 'apple'},
  {name: 'milli', froit: 'banana'},
  {name: 'muffin', froit: 'lemon'},
]
for (const state of states) {
  // Error : 'state'에 'fruit' 속성이 없습니다.
  console.log(state.fruit);
}

// good
interface State {
  name: string;
  fruit: string;
}

const states: State[] = [
  // Error: 'state'에 'froit' 속성이 없습니다.
  {name: 's', froit: 'apple'},
  {name: 'milli', froit: 'banana'},
  {name: 'muffin', froit: 'lemon'},
]
  • TypeScript 타입 시스템은 JavaScript의 런타임 동작을 모델링함
    • 의도하지 않은 이상한 코드가 오류를 발생시킬 수 있음
const x = '2' + 3; // 정상, string 타입
const x = 2 + '3'; // 정상, string 타입

const a = null + 7;
// a = 7 in JS
// Error : + 연산자를 ... 형식에 적용할 수 없음 in TS

const b = [] + 12;
// b = 12 in JS
// Error : + 연산자를 ... 형식에 적용할 수 없음 in TS

alert('Hello', 'TypeScript');
// 'Hello' 경고를 표시함 in JS
// Error: 0 ~ 1개의 인수가 필요한데 2개를 가져옴
  • 타입 체크를 통과하더라도 여전히 런타임에 오류가 발생할 수 있음
const names = ['s', 'milli', 'muffin'];
console.log(names[3].toUpperCase());
// TypeError: Cannot read property 'toUpperCase' of undefined

1.2 TypeScript 설정 이해하기

  • TypeScript 설정은 커맨드 라인을 이용하기보다는 tsconfig.json을 사용하는 것이 좋음

  • TypeScript 컴파일러는 언어의 핵심 요소에 영향을 미치는 몇 가지 설정을 포함하고 있음

    • 설정을 제대로 하려면 noImplicitAnystrictNullCheck를 이해해야함

noImplicitAny

  • noImplicitAny : 변수들이 미리 정의된 타입을 가져야 하는지 여부를 제어함
// noImplicitAny : false
function add(a, b) {
  // a 매개변수에 암시적으로 any 형식이 포함됨
  // b 매개변수에 암시적으로 any 형식이 포함됨
  return a + b;
}

// noImplicitAny : true
// Error
function add(a, b) {
  return a + b;
}
  • noImplicitAny가 설정되었을 때 오류 해결 방법
    • 명시적으로 any 타입임을 선언함
    • 더 분명한 타입을 선언함
// noImplicitAny : true
function add(a: any, b:any) {
  return a + b;
}

function add(a: number, b:number) {
  return a + b;
}
  • noImplicitAny를 설정하여 코드를 작성할 때 장점

    • TypeScript가 문제를 발견하기 수월해짐
    • 코드의 가독성이 좋아짐
    • 개발자의 생산성이 향상됨
  • JavaScript로 되어 있는 기존 프로젝트를 TypeScript로 전환하는 상황에만 noImplicitAny 설정을 해제하는 것이 좋음

strictNullChecks

  • strictNullChecks : null과 undefined가 모든 타입에서 허용되는지 확인하는 설정
// strictNullChecks : false
const x: number = null; // 정상, null은 유효한 값임
const x: number = undefined; // 정상, undefined은 유효한 값임

// strictNullChecks : true
const x: number = null; // Error: null 형식은 number 형식을 할당할 수 없음
const x: number = undefined; // Error: undefined 형식은 number 형식을 할당할 수 없음
  • strictNullChecks는 null과 undefined 관련된 오류를 잡아내는 데 많은 도움이 됨

    • "undefined는 객체가 아닙니다"와 같은 런타임 오류를 방지하기 위해서 strictNullChecks를 설정하는 것이 좋음
  • strictNullChecks를 설정하려면 noImplicitAny를 먼저 설정해야함

  • 언어에 의미적으로 영향을 미치는 설정들(noImplicitThis, strictFunctionTypes, noImplicitAny, strictNullChecks 등)를 모두 설정하고 싶다면 strict 설정을 하면 됨


Quiz

  1. 런타임에 타입 정보를 유지하는 방법에 대해 아는 대로 얘기해보세요.
  2. 구조적 타이핑에 대해 설명해보세요.
  3. any 타입을 지양하는 이유에 대해 설명해보세요.

0개의 댓글