이전에 type alias 를 이용해서 타입을 변수처럼 저장해 사용하는 방법을 배웠다.
추가로, object 에 타입을 지정할 때 interface 라는 키워드를 이용할 수도 있다.
interface
interface Student{
name: string
}
interface Teacher{
name: string,
age: number
}
let 학생: Student = {name:'kim'}
let 선생: Teacher = {name:'kim', age:20}
interface 는 type 키워드 처럼 사용할 수 있는 키워드이다.
interface 의 장점은 extends 를 할 수 있다는 것이다.
예를 들어 위의 코드를 아래와 같이 쓸 수도 있다.
interface Student{
name: string
}
interface Teacher extends Student{
age: number
}
let 학생: Student = {name:'kim'}
let 선생: Teacher = {name:'kim', age:20}
아까 코드에서는 name 이 중복된다.
하지만 위 코드처럼 extends Student 를 해주면
Student 안에 있는 속성들이 Teacher 에도 적용된다.
그래서 아까 전의 코드와 똑같은 기능을 한다고 볼 수 있다.
type 과 interface 의 차이
둘은 거의 똑같은 기능을 제공한다.
차이점이 있다면 extends 를 하는 문법이 조금 다르다
interface Animal {
name :string
}
interface Cat extends Animal {
legs :number
}
예를 들어 interface 에서는 extends 를 하는 방법이 아까처럼 이렇게 적는다면
type Animal = {
name :string
}
type Cat = Animal & { legs: number }
type 은 extends 를 할 때 & 기호를 사용한다.
이렇게 하면 Animal 과 { legs: number } 라는 object 2개를 합칠 수 있다.
이렇게 되면 Cat 타입은 name, legs 속성을 모두 갖게 된다.
하지만 interface 도 type처럼 & 기호를 쓸 수 있긴하다.
interface Student {
name :string,
}
interface Teacher {
age :number
}
let 변수 :Student & Teacher = { name : 'kim', age : 90 }
위의 '변수' 라는 변수는 Student 와 Teacher 라는 interface 를 모두 합친게 된다.
& 기호 사용하는 것을 intersection 이라고 한다.
이는 extends 와 유사하게 사용가능한 문법이다.
중복 선언 가능 여부
interface 와 type alias 의 중복 선언이 가능한지에 대해 알아보자
먼저 interface 의 경우이다.
interface Animal {
name :string
}
interface Animal {
legs :number
}
interface 의 경우 타입이름 중복 선언을 허용해주며 extends 와 동일하게 동작한다.
예를 들어 위처럼 코드를 작성하면 Animal 이라는 타입은 이제 name 과 legs 라는 속성 모두를 갖게된다.
이렇게 했을 시 장점이 있다면,
type 선언을 자주 사용하는 라이브러리를 내가 이용할 경우, type 선언을 덮어쓰기 하거나 override 가능하다는 것이다.
type Animal = {
name :string
}
type Animal = {
legs :number
}
반면 type alias 는 중복 선언을 허용하지 않는다.
더 엄격하다고 할 수 있다.
interface 와 type 중에서 무엇을 써야할까
일반적인 상황에서는 type 키워드를 활용하더라도,
다른사람이 내가 작성한 코드를 활용할 일이 많다면 interface 로 유연하게 작성하는 것이 좋다.
그래서 타입스크립트로 작성된 라이브러리 중에 interface 로 타입지정한 게 많다고 한다.
또는 object 자료형은 interface 로 타입지정해놓고
다른 자료형들은 type 으로 타입지정하는 것도 괜찮을 것 같다.
extends 안되는 경우
당연할 수도 있지만 짚고 넘어가면 좋을 것 같은 사례들을 알아보자
interface Animal {
name :string
}
interface Dog extends Animal {
name :number
}
위와 같은 경우는 name 속성이 Dog 에서 중복되기 때문에 에러가 난다.
interface Animal {
name :string
}
interface Dog {
name :number
}
let 변수 :Dog & Animal = { name : '멍멍' }
위와 같은 경우 또한 & 로 Animal 과 Dog 를 합쳐서 name 속성이 중복된다
이렇게 되면 name 속성이 string 인지 number 인지 애매하다
따라서 에러가 난다.
연습해보기
let 장바구니 = [ { product : '청소기', price : 7000 }, { product : '삼다수', price : 800 } ]
이렇게 생긴 장바구니 array 에 대해 타입을 지정해보자(interface 키워드 이용해서)
interface CartItem {
product: string,
price: number
}
let 장바구니 :CartItem[] = [ { product : '청소기', price : 7000 }, { product : '삼다수', price : 800 } ]
이번에는 위에서 만든 타입을 extends 해보자
product, price 말고도 card 라는 속성을 추가하면 된다.
여기서 card 는 boolean 타입이다.
interface CartItem {
product: string,
price: number
}
interface NewCartItem extends CartItem {
card: boolean
}
답은 위와 같다.
object 안에 함수를 두 개 넣을 것이다.
이 object 자료는 plus() 함수가 내부에 있고, plus 함수는 파라미터 두개 입력하면 더해서 return 한다
또한 minus() 함수도 있는데 파라미터 2개 입력하면 빼서 return 한다.
interface myFunc{
plus: (a:number,b:number)=>number,
minus: (a:number,b:number)=>number
}
let 내함수: myFunc = {
plus(a,b){
return a+b
},
minus(a,b){
return a-b
}
}
답은 위와 같다.
ref: 코딩애플