아래 예제에서 타입스크립트 컴파일러가 getFullName()
으로 넘어간 인자가 2개의 property를 가지고 모두 string인지 확인해서 맞으면 통과시켜줌.
function getFullName(person: {
firstName: string;
lastName: string
}) {
return `${person.firstName} ${person.lastName}`;
}
let person = {
firstName: 'John',
lastName: 'Doe'
};
console.log(getFullName(person));
// Output
John Doe
위 처럼 했을때 함수 인자의 타입 선언이 가독성이 별로 않좋기 때문에 타입스크립트는 인터페이스를 제공함.
아래는 2개의 string property를 가진 Person
이라는 인터페이스임.
interface Person {
firstName: string;
lastName: string;
}
인터페이스 이름은 camel case로 정함. 위처럼 Person
인터페이스를 정의하면 이 인터페이스를 타입으로 사용할 수 있어 코드가 위보다 가독성이 좋아짐.
function getFullName(person: Person) {
return `${person.firstName} ${person.lastName}`;
}
let john = {
firstName: 'John',
lastName: 'Doe'
};
console.log(getFullName(john));
이제 getFullName()
함수는 2개의 string property를 가진 인자를 받게됨. 근데 정확히 2개의 string property를 가질 필요는 없음.
let jane = {
firstName: 'Jane',
middleName: 'K.'
lastName: 'Doe',
age: 22
};
위는 4개의 property를 가진 객체인데 이 객체가 firstName
과 lastName
property를 가지고 있기에 아래처럼 getFullName()
함수에 넣을 수 있음.
let fullName = getFullName(jane);
console.log(fullName); // Jane Doe
인터페이스는 optional property를 가질 수 있음. optional property를 선언하려면 ?를 property 이름 끝에다가 선언해주면됨.
interface Person {
firstName: string;
middleName?: string;
lastName: string;
}
위 인터페이스는 2개의 property와 1개의 optional property를 가지고 있음.
아래는 바로 위에서 만든 인터페이스를 사용한 getFullNmae()
함수임.
function getFullName(person: Person) {
if (person.middleName) {
return `${person.firstName} ${person.middleName} ${person.lastName}`;
}
return `${person.firstName} ${person.lastName}`;
}
let asd = {
firstName: 'fisrt',
lastName: 'second',
middleName: 'middle'
}
console.log(getFullName3(asd)); // fisrt middle second
property를 객체가 처음 만들어졌을때를 제외하고 수정불가능하게 만드려면 readonly
키워드를 property 이름앞에 사용하면됨.
interface Person {
readonly ssn: string;
firstName: string;
lastName: string;
}
let person: Person;
person = {
ssn: '171-28-0926',
firstName: 'John',
lastName: 'Doe'
}
// 아래 줄은 에러나옴
person.ssn = '171-28-0000';
// error
error TS2540: Cannot assign to 'ssn' because it is a read-only property.
Code language: TypeScript (typescript)
인터페이스는 function type도 표현가능함.
interface StringFormat {
(str: string, isUpper: boolean): string
}
// 그냥 let asd: number; 처럼 타입 명시한거랑 같음
let format: StringFormat;
format = function (str: string, isUpper: boolean) {
return isUpper ? str.toLocaleUpperCase() : str.toLocaleLowerCase();
};
console.log(format('hi', true));
// Output
HI
parameter의 이름이 인터페이스에 정의한거랑 같지 않아도 됨. 아래는 위랑 동일한 결과가 나옴.
let format: StringFormat;
format = function (src: string, upper: boolean) {
return upper ? src.toLocaleUpperCase() : src.toLocaleLowerCase();
};
console.log(format('hi', true));
StringFormat
인터페이스는 함수의 인자로 string
과 boolean
만 넣기만 하면 됨.
심지어 아래처럼 두 번째 인자가 없어도 동작함. 두 번째 인자인 false는 lowerCase()
함수가 불러졌을 때 넘어가기는함.
let lowerCase: StringFormat;
lowerCase = function (str: string) {
console.log(arguments);
return str.toLowerCase();
}
console.log(lowerCase('aaaaaaaai', false));
// Output:
[Arguments] { '0': 'aaaaaaaai', '1': false }
aaaaaaaai
아래의 Json
인터페이스는 관련없는 클래스에서도 가져다 쓸 수 있음.
interface Json {
toJSON(): string
}
아래는 Json
인터페이스를 적용한 클래스로 Json
의 메소드인 toJson()
를 구현했음.
class Person implements Json {
constructor(private firstName: string,
private lastName: string) {
}
toJSON(): string {
return JSON.stringify(this);
}
}
let person = new Person('John', 'Doe');
console.log(person.toJSON());
// Output
{"firstName":"John","lastName":"Doe"}
- 인터페이스는 optional property나 readonly property를 가질 수 있음
- 인터페이스는 function type에서도 사용가능함
- 인터페이스는 클래스 타입으로 보통 사용됨