타입스크립트 코드 작성시 인터페이스를 사용하는 이유는 아래와 같습니다.
타입 체킹(Type Checking)
인터페이스를 사용하면 객체의 구조를 정의할 수 있습니다. 이를 통해 타입스크립트는 해당 객체가 인터페이스에 정의된 구조와 일치하는지 확인할 수 있어, 타입 관련 오류를 미리 감지하고 방지할 수 있습니다.
코드의 가독성 및 유지보수 향상
인터페이스는 객체의 구조를 명확하게 설명해줍니다. 이는 코드의 이해를 돕고, 다른 개발자들이 코드를 읽고 수정하기 쉽게 만들어줍니다.
계약(Contract)으로서의 역할
인터페이스는 클래스나 함수가 따라야 할 '계약'과 같습니다. 이 계약을 통해 개발자들은 어떤 프로퍼티나 메서드가 필요한지, 어떤 타입이어야 하는지 명확히 알 수 있습니다.
재사용성 및 확장성 증가
인터페이스를 통해 공통의 구조를 정의하고, 여러 곳에서 재사용할 수 있습니다. 또한 인터페이스는 확장 가능해서 새로운 기능을 쉽게 추가할 수 있습니다.
의존성 역전 원칙(Dependency Inversion Principle)
인터페이스는 고수준 모듈과 저수준 모듈 사이의 의존성을 역전시키는 데 도움을 줍니다. 이는 소프트웨어 설계의 유연성을 증가시키는 중요한 원칙 중 하나입니다.
통합 및 테스팅 용이성
인터페이스를 사용하면 모듈 간의 통합이 용이해지고, 테스트(특히 모의 객체(Mock Objects)를 사용한 단위 테스트)가 더 쉬워집니다.
종합하면, 타입스크립트의 인터페이스는 타입 안정성, 코드의 가독성 및 유지보수성 향상, 그리고 소프트웨어 설계의 유연성과 테스트 용이성을 제공합니다.
아래 코드는 에러를 발생시킵니다.
let User:object;
user:User{
name:'kim',
age:31
}
console.log(user.name)
//Error : 'object' 형식에 'name' 속성이 없습니다.
에러 발생 이유 : 타입스크립트에서 object 타입은 구체적인 속성에대한 정보는 가지고 있지 않습니다. 즉,user 객체는 어떠한 속성도 가지고있지 않다고 가정합니다.
그래서 우리는 인터페이스라는 형식의 객체구조를 미리 선언하게 됩니다.
interface User {
name:string;
age:number;
}
const user : User {
name:'kim',
age:31
}
이렇게 선언된 인터페이스를 타입으로 가지는 객체는 인터페이스의 구조와 같은 구조로 사용해야합니다.
interface User {
name:string;
age:number;
nick:string;
}
const user : User { //Error : 인터페이스에 nick 속성을 정의하지 않음
name:'kim',
age:31
gender:'male' //Error : 인터페이스에 없는 속성을 사용
}
인터페이스에 정의되지 않은 속성을 사용하거나, 인터페이스에 정의되어있는 속성을 사용하지 않으면 에러가 발생합니다.
인터페이스는 계약사항 입니다. 인터페이스를 타입으로 정한 객체, 함수 등은 반드시 인터페이스의 정의된 규칙으로 작성해야합니다.
옵셔널 속성 (optioner property)
옵셔널 속성은 사용해도되고 안해도되는 말그대로 옵션입니다. ?기호를 이용하여 속성명?:type 의 형태로 정의된 속성은 옵셔널 속성이 됩니다.
interface Optioner{
option1:string;
option2?:string;
option3?:string;
}
const obj:Optioner = {
option1:'option',
option3:'option'
}//Error : option2 를 사용하지 않아도 에러가 발생하지 않습니다.
읽기 전용 속성( readonly property )
읽기 전용 속성은 변경할 수 없는 조회만 가능한 속성을 지정할 때 사용합니다.
interface ReadOnly{
readonly property1:string;
property2:string;
property3:string;
}
const obj:ReadOnly = {
property1 : 'readonly property',
property2:'property',
property3:'property',
}
obj.property1 = 'property' //Error : 값을 변경하려고하면 에러가 발생합니다.
인덱스 서명( index signature )
타입스크립트의 인덱스 서명은 객체의 key 에 타입을 정의하는 것입니다. 객체의 key 는 문자열, 숫자 두 종류를 사용할 수 있습니다. 따라서
두 종류의 인덱스 서명이 있습니다.
인덱스 서명을 사용하는 것은 객체의 속성이 동적일 때 매우 유용하지만, 타입 안정성을 유지하면서 유연한 객체 구조를 제공하기 위해 주의 깊게 사용해야 합니다.
인덱스 서명을 사용하면,
동적으로 객체 속성을 받아들일 수 있습니다.즉, 인터페이스에 일일히 속성을 정의하지 않아도 된다는 말입니다.
문자열 인덱스 서명 ( String Index Signature )
interface Obj { //Obj 인터페이스 설정
[property : string] : string
// 객체 속성이 string 타입이면 값은 반드시 string 이어야한다. 고 정의한것.
}
const obj:Obj = {
prop1 : 'prop1',
prop2 : 1, //Error : 'number' 형식은 'string' 형식에 할당할 수 없습니다.
prop3 : 'prop3',
10 : 10 //Error :'number' 형식은 'string' 형식에 할당할 수 없습니다.
}
Obj 타입을 가진 객체는 동적으로 속성을 생성할 수 있게 되었습니다. 다만, 속성이 string 타입이면 반드시 값도 string 이어야 합니다.

객체의 속성을 동적으로 생성할 수 있게 된만큼, 제한적인 사항들이 생겼습니다.
인덱스 서명에 사용한 property 속성은 어디로 사라졌나요..?
인덱스 서명에 사용되는 key 는실제 객체의 키가 아니라, 인덱스 서명을 정의할 때 사용하는 임시 변수(placeholder)입니다. 이 변수들은 인덱스 서명의 형식을 정의하는 데 사용되며, 실제 객체의 속성 키로 사용되지 않습니다.
정리
- 인덱스 서명은 타입스크립트에서 객체 속성을 동적으로 생성 할 수 있게 해준다.
- 정의된 key 타입을 가지는 속성은 반드시 값도 정의된 타입과 일치해야한다.
즉,속성의 타입이 이거면, 값의 타입은 이것만 받아라고 강제하는것이다.- 자바스크립트
객체의 key 는 모두 문자열로 간주한다. 숫자도 문자열로 간주
주의사항
JavaScript에서 객체의 키는 항상 문자열로 변환됩니다. 따라서 타입스크립트에서 숫자 인덱스 서명을 사용하면, 이는 자동으로 문자열 인덱스 서명으로도 간주됩니다. 즉, 숫자 인덱스 서명을 정의하면 해당 객체는 문자열 키에 대해서도 동일한 타입의 값을 가질 수 있어야 합니다.
인터페이스는 지켜야하는 규칙을 만드는 것과 같습니다. 함수도 인터페이스를 이용하여 규칙을 정해줄 수 있습니다.
interface addFunc = {
(val1:number, val2:number):number
//( 매개변수의 갯수와 타입 정의 ):리턴타입 정의
}
const add:addFunc = (x,y) => { //매개변수의 이름은 자유롭게 작성 가능
return x+y;
}
//위의것과 같은 행위를 하는 함수입니다.
const add = (x:number, y:number):number => {
return x+y
}
두 함수의 차이를 봐주시면 됩니다.
클래스의 implements 키워드는 해당 인터페이스에 정의된 모든 속성과 메서드를 구현하겠다는 것을 의미합니다.
interface User {
name:string,
age:number
}
class userClass implements User {
height;
constructor(height:number){ //생성자 함수
this.height = height;
}
name = 'kim';
age = 31;
}
const kth = new userClass(175)