본문 바로가기

패스트캠퍼스

작성자와 사용자의 관점으로 코드 바라보기 [패스트캠퍼스 챌린지 18일차]

to 이해 typesystem

타입 시스템

  1. 사용하는 타입을 컴파일러에게 명시적으로 지정하는 시스템
  2. 컴파일러가 자동으로 타입을 추론하는 시스템

TS의 타입 시스템

타입을 명시적으로 지정할 수 있음

타입을 명시적으로 지정하지 않으면?
→ TS 컴파일러가 자동으로 타입을 추론

타입은 해당 변수가 할 수 있는 일을 결정함

(해석) f1이란 함수는 a를 인자로 받아서 a를 리턴

f1함수 안에서 a를 받은 다음에 a가 뭔가를 하겠죠?

근데 이 'a가 할 수 있는 일'이란 것은 a가 무슨 타입이냐에 따라서 달라짐

→ a의 타입은 a가 할 수 있는 일을 결정하게 됨

//JS
function f1(a) { 
    return a;      
}

함수 사용법에 대한 오해를 야기하는 JS

함수의 작성자는 매개변수 a가 number타입이라는 가정으로 함수를 작성

→ 함수 실행의 결과인 NaN이 의도한 것이 아니라면??

//JS
function f2(a) {
    return a * 38;
}
console.log(f2(10)); //380
//사용자가 사용법을 숙지하지 않은 채 문자열을 사용하여 함수 실행
console.log(f2('Happy')) // NaN

NaN도 넘버의 하나

TS의 추론에 의지하는 경우 (위와 똑같은 코드를 in TS)

TS에서는 타입이 지정되어 있지 않으면 TS가 직접 추론을 함
→ 그런데 한계가 있지

(결론) 어쨌든 NaN이라는 값이 나오는 게 의도된 게 아니라면, 올바르지 않은 함수임

//TS
function f3(a) { //function f3(a: any): number  함수 f3의 매개변수 a는 any로 추론됨
  return a * 38;
}
console.log(f3(10)); //380 
console.log(f3('Mark')+5) //NaN

타입이 지정이 안되어 있으면 any로 추론
→ 위험!!

→ 이 위험한 요소를 없애기 위해서 !
이런 형태를 아예 작성자가 사용할 수 없도록 하는 컴파일 옵션 있음


noImplicitAny 옵션 on

→ 실수를 줄이기 위해서

타입을 명시적으로 지정하지 않은 경우에
타입스크립트가 추론 중 'any'라고 판단하게 되면
컴파일 에러 발생시킴으로써
타입을 명시적으로 지정하도록 유도

noImplicitAny에 의한 방어

(에러) TS 왈 '이게 any인데...정말 any면 any라고 써! 아니면 다른 타입을 지정해줘!'


매개변수 타입은 명시적으로 지정/ 함수 리턴 타입은 명시적으로 지정 X

매개변수의 타입은 명시적으로 지정

함수의 리턴 타입은 명시적으로 지정 X → number | undefined 로 추론됨
(원래 number만 추론됐었는데 업데이트 된 듯
→ 이 문제 때문에 아래의 strictNullChecks 옵션 켜라! 이 내용)

function f4(a: number) { //function f4(a: number): number | undefined
    if(a > 0){
        return a * 38;
    }
}
//a가 0이거나 양수가 아니면 undefined
console.log(f4(5)); //190  -> function f4(a: number): number | undefined
console.log(f4(-5)+5) // f4(-5) 이 객체가 undefined인 것 같다고 에러 뜸

NaN가 의도된 결과가 아니기 때문에 런타임 상에서 문제 발생

컴파일 타임에는 number 혹은 undefined로 나오는 게 맞고

런타임 상에서는
저 결과물이 undefined인 경우에는 error를 throw한다던가 하는 식으로 막고,
number일 때만 연산을 하도록 조정을 해줘야 함

이게 TS의 시스템이 JS 개발자한테 제시하는 안전하게 코드를 짜는 방안


strictNullChecks 옵션 on

모든 타입에 자동으로 포함되어 있는 null과 undefined를 제거해줌

지금 내 vs code에서는 이 옵션을 안 켜도 undefined 에러가 떠서 읭?

TS가 업데이트가 된 건지 뭔지는 모르겠지만...

여튼 이 옵션을 키는 게 런타임 문제를 줄여주고 스트릭트해서 추천


명시적으로 리턴 타입을 지정해야 할까?

리턴 타입도 명시적으로 지정해주는 걸 추천

왜냐?

작성자의 입장에서 이 코드를 작성할 때
'이 코드는 number를 인자로 받고 number로 리턴할 것이다'라는 걸 먼저 계획하고,
이에 맞춰서 함수 안에 로직을 작성할 때 명시한 타입과 실제 리턴 타입이 일치가 되는지를 TS가 봐주기 때문에 검토하면서 코딩 작업을 할 수 있음

function f4(a: number): number { //에러에러!
//함수에 끝 return 문이 없으며 반환 형식에 'undefined'가 포함되지 않습니다.
  if (a > 0) {
    return a * 38;
  }
}

noImplicitReturns 옵션 on

함수 내에서 모든 코드가 값을 리턴하지 않으면 컴파일 에러를 발생시킴

function f5(a: number) { //return type 명시 안 한 게 문제가 아니야
    if(a > 0) {
        return a * 38;
    }
}

if인 경우에는 리턴 하지만

if가 아닌 경우에는 리턴하지 않고 코드가 종료되잖아

이렇게 하면 알아서 undefined가 추론되지
(이건 의도하지 않았을 때 문제되니까)

→ 이런 경우에 else일 때의 경우를 명시해주라고 에러 뜸

Not all code paths return a value


매개변수에 object가 들어오는 경우

//JS
function f6(a) {
  return `이름은 ${a.name}이고, 연령대는 ${
    Math.floor(a.age / 10) * 10}대 입니다.`;
  }
  console.log(f6({name:'Mark', age:38}));
// 이름은 Mark이고, 연령대는 30대입니다
  console.log(f6('Mark'));
// 이름은 undefined이고, 연령대는 NaN대입니다.
// 이건 잘못된 거

위의 잘못된 걸 막기 위해 매개변수에 object를 명시해줘야 함

object literal type

object literal type으로 a의 타입을 지정해 줄 수 있음

//TS
function f7(a: { name: string; age: number }): string {
  return `이름은 ${a.name}이고, 연령대는 ${
    Math.floor(a.age / 10) * 10
  }대 입니다.`;
}

console.log(f7({ name: "Mark", age: 38 }));
console.log(f7("Mark")); //에러!
/*
'string' 형식의 인수는 
'{ name: string; age: number; }' 형식의 매개 변수에 
할당될 수 없습니다.ts(2345)
*/

근데 매번 저렇게 오브젝트 리터럴 타입 길게 쓰는 거 번거롭잖아

→ 특정한 타입으로 뽑아서 타이핑을 만들어 놓는 방식 있음


나만의 타입을 만드는 방법

여러가지가 있음

interface, type, class

이런 것들을 이용해서
읭?

타입의 이름을 쓰고 그 이름으로 비교를 해서 문제가 있는지 없는지 에러를 확인하는 거?

읭?

여튼 예시

interface PersonInterface {
  name: string;
  age: number;
}

type PersonTypeAlias = {
  name: string;
  age: number;
};

function f8(a: PersonInterface): string {
  return `이름은 ${a.name}이고, 연령대는 ${
    Math.floor(a.age / 10) * 10
  }대 입니다.`;
}

console.log(f8({ name: "Mark", age: 38 }));
//이름은 Mark이고 연령대는 30대입니다
console.log(f8("Mark")); //error!
/*
 'string' 형식의 인수는 'PersonInterface' 형식의 매개 변수에 할당될 수 없습니다.ts(2345)
function f8(a: PersonInterface): string
 */


책상이 어지럽네
내 머리속도 그래

https://bit.ly/37BpXiC
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
#직장인인강 #직장인자기계발 #패스트캠퍼스 #패스트캠퍼스후기 #패캠챌린지 #한번에끝내는프론트엔드개발초격차패키지Online