정말 많이 쓰는 것으로 타입 별칭과 매우 유사하다
type Point = {
x: number;
t: number;
}
interface Point {
x: number;
t: number;
}
보면 그냥 앞만 다르지 똑같아 보인다. 물론 인터페이스는 객체에만 사용된다는 점은 다르다.
따라서 유니온 타입에 인터페이스를 쓰긴 불가능 하고 타입 별칭에선 가능하다
타입 별칭을 통해 객체 타입을 사용할 때와 동일한 방식으로 작동한다.
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;
}
이는 인터페이스를 재선언 하는 것이 아닌 이 둘이 하나의 조합이 되기 때문이다.
인터페이스를 다시 열어 Person
은 age
또한 가지고 있다고 지정하는 것!
다른 곳에 있는 파일에 작업한 인터페이스가 있거나 할 때 언제든 추가하여 조합할 수 있다.
인터페이스의 또다른 유용한 기능인 인터페이스의 확장으로 다른 인터페이스로부터의 상속기능이다
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;
}
이처럼 &
를 사용한 교차 타입을 사용해야 한다.
이처럼 둘은 매우 유사하지만 다르기 때문에 접근이 달라야 한다는 것을 기억하자
터미널에서 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가지 옵션이 있다
include 와 exclude인데 files
옵션과 관련이 있어 헷갈릴 수 있다.
include
를 사용해 전체 디렉터리를 포함하도록 설정한다."include" : ["src/**/*","tests/**/*"]
처럼 exclude
를 사용하여 제외할 파일을 설정하는 것!일단 include의 기본값은 **
로 모든 파일이기 때문에 해당 tsconfig
가 있는 파일위치에서 전부 확인한다.
exclude를 이용해 무시할 파일 이름 또는 패턴의 배열을 지정하면 typesciprt는 해당 파일을 컴파일하지 않고 include설정의 결과만 컴파일한다.
exclude 또한
"exclude" : ["경로/파일명.ts"]
식으로 선언해준다. 하지만 exclude는 기본값을 조심해야 하는데 프로젝트에 보통 node_module
이 있는 경우가 있을것이다.
그 안에는 ts파일을 포함한 여러 의존성이 다운로드 될 가능성이 크기 때문에 Typescript가 자동으로 제외한다.
exclude옵션을 사용해 제외하고 싶은 항목을 지정했다면 꼭 node_modules를 추가해야한다.
반드시 제외해서 의존성이 컴파일 되지 않도록 하자!
Dir은 Directory의 줄임말로 Outdir를 사용하면 Typescript가 컴파일된 Javascript 파일을 내보낼 위치를 지정할 수 있다.
지정하지 않을 경우에는 자동적으로 Typescript 파일 옆에 위치한다
이는 대부분 선호하지 않는 방식으로 대규모 프로젝트에서는 보통 src디렉터리 또는 특정 디렉터리에 Typescript파일을 모아둔다 ts파일에 상응하는 js파일은 별도의 디렉터리에 컴파일 되고
HTML파일이나 노드 앱등이 접속해서 JS파일을 실행한다
보통 dist나 src라는 이름을 많이 붙인다!
tsconfig
파일에서 주석으로 있으니 찾기를 이용해 outDir
옵션을 찾아보자
이후 경로를 입력해주면 된다!
TS를 컴파일한 JS버전을 제어하는 target 옵션이다.
지금은 만들경우 es5
로 설정되어 있을 텐데 es
뒤에 어떤 값을(물론 존재하는 JS버전이어야 한다) 넣어도 허용된다.
true
가 기본값으로 엄격한 타입 검사 옵션을 모두 활성화 한다.
Typescript 전체의 타입 검사 , 추가 규칙, 제약 조건이 활성화
최종결과의 완성도를 보장하기 위해 가능한 모든 확인을 거치는 것이다.
우리가 지나칠 수 있었던 암시적 any
또한 strict
옵션중에 있는 noImplicitAny
에 걸려 에러가 발생한다.
또 하나의 중요한 건 strictNullChecks
로 null
이나 undefined
할당에 대해 엄격하게 관리할 수 있다