Typescript - 5

hoin_lee·2023년 7월 23일
0

TypeScript

목록 보기
7/14

interface

정말 많이 쓰는 것으로 타입 별칭과 매우 유사하다

type Point = {
  x: number;
  t: number;
}
interface Point {
  x: number;
  t: number;
}

보면 그냥 앞만 다르지 똑같아 보인다. 물론 인터페이스는 객체에만 사용된다는 점은 다르다.
따라서 유니온 타입에 인터페이스를 쓰긴 불가능 하고 타입 별칭에선 가능하다

readonly와 선택적 인터페이스 프로퍼티

타입 별칭을 통해 객체 타입을 사용할 때와 동일한 방식으로 작동한다.

interface Person {
  readonly id: number;
  first: string;
  last: string;
  nickname?: string;
}

이처럼 이전에 배웠던 방식하고 똑같이 사용할 수 있다.
그러면 메서드를 사용하려면 어떻게 할까?

interface Person {
  readonly id: number;
  first: string;
  last: string;
  nickname?: string;
  sayHi: ()=> string  //메서드 추가
}

위 처럼 작성하게 되면 아무것도 인수로 받지 않고 return값에 문자열을 반환하겠다는 얘기이다.
또 다른 구문으로도 작성할 수 있는데 sayHi():string 이다 위에선 화살표 구문을 사용했고 이건 프로퍼티 이름뒤에 바로 괄호를 통해 메서드임을 표시 해주고 : 뒤로 반환값을 표시한 것!
인수를 받고 싶다면 (name:string) => string; 처럼 이전번과 같이 표시해주면 된다.
다른 구문도 똑같이 sayHi(name:string) : string이렇게 표현해주면 된다.

인터페이스 조합

type Person = {
  name : string;
}
type Person = {  // 중복되었다는 error발생
  age : number;
}
interface Person {
  name : string;
}
interface Person {  // 에러 없음!
  age : number;
}

이는 인터페이스를 재선언 하는 것이 아닌 이 둘이 하나의 조합이 되기 때문이다.
인터페이스를 다시 열어 Personage또한 가지고 있다고 지정하는 것!
다른 곳에 있는 파일에 작업한 인터페이스가 있거나 할 때 언제든 추가하여 조합할 수 있다.

인터페이스 확장

인터페이스의 또다른 유용한 기능인 인터페이스의 확장으로 다른 인터페이스로부터의 상속기능이다

interface Dog {
  name: string;
  age: number;
}
interface Dog {
  breed: string;
  bark(): string;
}

interface ServiceDog extends Dog {
  job : "drug sniffer" | "bomb" | "guide dog";
}

이런식으로 이미 Dog로 타입을 만들어 놓고 사용하고 있다가 역할을 가진 Dog타입을 만들고 싶어 ServiceDog를 만들었을 때 똑같이 name부터... 쭉 작성하는 것이 나닌 extends를 사용하여 Dog를 상속하여 Dog가 가진 값들을 모두 가지게 한다음 아래에 새롭게 추가하여 새로운 ServiceDog 타입을 만들수 있다
즉 , 상속받은 ServiceDog 타입은 Dog가 가진 name부터 bark()까지 모두 가지고 있고 추가로 job이란 타입까지 가지고 있는 것이다.

여러가지 다중상속을 한다면?

interface Person {
  name : string;
}

interface Employee {
  readonly id: number;
  email: string
}

interface Engineer extends Person,Employee {
  level: string;
  languages: string[]
}

위와 같이 ,를 통해 여러개를 다중상속 할 수 있다.
이경우 Engineer란 타입은 name, id, email을 모두 가지고 있고 추가로 level,languages란 타입을 가지고 있는 것이다!

인터페이스와 타입 별칭

타입 별칭과 매우 유사하지만 별칭 대신에 인터페이스를 왜 사용해야 하는가? 이다
대부분의 작업은 동일하지만 핵심적인 차이점이 존재한다.
인터페이스는 일단 객체만의 형태로 존재할 수 있다
한마디로 모든 종류의 타입 별칭을 인터페이스로 대체할 수는 없는 것!

객체 형태를 묘사하는 경우가 아니라면 타입 별칭을 사용해야 한다.
또 다른 차이점으론 위에서 했던 것처럼 인터페이스를 다시 열어 내용을 추가하는 것이 가능하다.
프로퍼티의 확장을 위해 extends를 사용햇는데 객체를 기반으로 한 접근법이다.
하지만 타입 별칭을 사용할때는

type Name = {
  name: string;
}
type Person =Name & {
  age: number;
}

이처럼 &를 사용한 교차 타입을 사용해야 한다.
이처럼 둘은 매우 유사하지만 다르기 때문에 접근이 달라야 한다는 것을 기억하자

typescript 환경

터미널에서 tsc --init 을 입력하면 tsconfig.json이라는 파일이 생성된다.
그리고 아무 ts파일을 만들어서 작성해보자

//index.ts
interface Chicken {
  breed: string;
  eggsPerWeek: number;
  name: string;
}

const norma: Chicken = {
  breed: "Silkie",
  eggsPerWeek: 4,
  name: "Norma",
};

와 같이 만든 후 터미널에tsc index.ts 입력해서 컴파일 한다

// index.js
var norma = {
    breed: "Silkie",
    eggsPerWeek: 4,
    name: "Norma"
};

와 같이 만들어진다.

감시모드

tsc --watch 이는 TS에게 단 한 번만 컴파일 하지 말라고 지시하는 옵션이다.
TS가 변경 사항이 발생하는지 항상 감시하고 index.ts파일을 변경하고 저장하면 자동으로 다시 컴파일 하도록 하는 것!

참고로 기본적인 tsc 명령어를 입력할 경우 모든 .ts파일을 컴파일링 하지만 tsc 파일명을 사용하면 해당 파일만 컴파일링한다.

컴파일러 옵션

tsconfig.json 파일로 들어가면 compilerOptions이란 게 있는데 그 안에 files옵션을 넣는 실수가 많다고 한다.
files옵션은 최상위 옵션으로 compilerOptions 외부에서 설정해야 한다.
방법으로는 typescript로 컴파일할 모든 파일을 나열하는 것이다. 파일이 많지 않은 소규모 프로젝트에서 가장 적합하다.
외부에서 "files" : ["index.ts","...","..."] 이런식으로 설정해주면 된다.
만약 수동으로 설정한다면 files를 이용하면 된다.

하지만 typescript에게 컴파일할 파일과 무시할 파일을 구분하는데 사용되는 2가지 옵션이 있다
includeexclude인데 files옵션과 관련이 있어 헷갈릴 수 있다.

  • 먼저 include를 사용해 전체 디렉터리를 포함하도록 설정한다.
  • "include" : ["src/**/*","tests/**/*"]처럼
  • 이후 exclude를 사용하여 제외할 파일을 설정하는 것!

일단 include의 기본값은 **로 모든 파일이기 때문에 해당 tsconfig가 있는 파일위치에서 전부 확인한다.
exclude를 이용해 무시할 파일 이름 또는 패턴의 배열을 지정하면 typesciprt는 해당 파일을 컴파일하지 않고 include설정의 결과만 컴파일한다.
exclude 또한

  • "exclude" : ["경로/파일명.ts"] 식으로 선언해준다.
  • 위는 특이하게 파일 명을 적을경우고 보통은 일종의 패턴, 즉 특정문자를 포함하는 파일을 모두 제외하도록 하는 게 보통이다!

하지만 exclude는 기본값을 조심해야 하는데 프로젝트에 보통 node_module이 있는 경우가 있을것이다.
그 안에는 ts파일을 포함한 여러 의존성이 다운로드 될 가능성이 크기 때문에 Typescript가 자동으로 제외한다.
exclude옵션을 사용해 제외하고 싶은 항목을 지정했다면 꼭 node_modules를 추가해야한다.
반드시 제외해서 의존성이 컴파일 되지 않도록 하자!

Outdir 옵션

Dir은 Directory의 줄임말로 Outdir를 사용하면 Typescript가 컴파일된 Javascript 파일을 내보낼 위치를 지정할 수 있다.
지정하지 않을 경우에는 자동적으로 Typescript 파일 옆에 위치한다

  • index.ts 가 컴파일 되면 바로 옆에 index.js가 생긴다

이는 대부분 선호하지 않는 방식으로 대규모 프로젝트에서는 보통 src디렉터리 또는 특정 디렉터리에 Typescript파일을 모아둔다 ts파일에 상응하는 js파일은 별도의 디렉터리에 컴파일 되고
HTML파일이나 노드 앱등이 접속해서 JS파일을 실행한다

보통 dist나 src라는 이름을 많이 붙인다!

tsconfig 파일에서 주석으로 있으니 찾기를 이용해 outDir옵션을 찾아보자
이후 경로를 입력해주면 된다!

Target 옵션

TS를 컴파일한 JS버전을 제어하는 target 옵션이다.
지금은 만들경우 es5로 설정되어 있을 텐데 es뒤에 어떤 값을(물론 존재하는 JS버전이어야 한다) 넣어도 허용된다.

Strict 옵션

true가 기본값으로 엄격한 타입 검사 옵션을 모두 활성화 한다.
Typescript 전체의 타입 검사 , 추가 규칙, 제약 조건이 활성화
최종결과의 완성도를 보장하기 위해 가능한 모든 확인을 거치는 것이다.
우리가 지나칠 수 있었던 암시적 any또한 strict옵션중에 있는 noImplicitAny에 걸려 에러가 발생한다.
또 하나의 중요한 건 strictNullChecksnull이나 undefined 할당에 대해 엄격하게 관리할 수 있다

추가적인 옵션들

  • "allowJs" : typescript의 프로그램 일부에 js파일을 사용할 수 있게 된다. typescript로 js파일을 가져온다
  • "checkJs" : typescript가 오류를 보고할 수 있다. js에서 수행되며 js파일에 오류가 있을 경우 문제가 어디 있는지를 알려주는 기능
  • "sourceMap" : typescript에 소스 맵의 생성 여부를 지시할 수 있다.
  • "noEmit" : 파일을 컴파일 하지 않아서 새 js파일을 만들어 내지 않도록 한다(타입 검사는 계속한다)
  • "noEmitOnError" : 컴파일 도중 오류가 생기면(타입검사에 문제) TS가 새로운 파일을 만들지 않게 하는 옵션이다. 오류가 없는 경우에만 컴파일된 JS파일을 얻는 것!
profile
https://mo-i-programmers.tistory.com/

0개의 댓글