인터페이스의 뜻은 연결하는 장치라는 뜻을 가지고 있다.
자바스크립트 ES6는 인터페이스를 지원하지 않지만 타입스크립트는 인터페이스를 지원하고 있다!
타입스크립트에서 인터페이스는 여러 객체를 정의하는 일종의 규칙이자 구조!
코드로 보면 이해가 더 잘가니 코드로 확인해보자!
인터페이스를 통해 특정 속성(메소드)등의 타입을 정의
***코드를 재사용하고 묶어준다는 점에서 class와 비슷한 너낌을 받았다.
=> 프로퍼티와 메소드를 가진다는 점에서 클래스와 유사하나 직접 인스턴스를 생성할 수 없다는 차이점이 존재!!
//***IUser에서 I는 Interface를 의마하는 별칭으로 사용했다!
interface IUser {
name: string,
age: number,
isAdult: boolean
}
let user1: IUser = {
name: 'Neo',
age: 123,
isAdult: true
};
// Error - TS2741: Property 'isAdult' is missing in type '{ name: string; age: number; }' but required in type 'IUser'.
let user2: IUser = {
name: 'Evan',
age: 456
};
여기서 : 콜론 이나 , 콤마를 사용하지 않을 수 있음!
interface IUser {
name: string,
age: number
}
// Or
interface IUser {
name: string;
age: number;
}
// Or
interface IUser {
name: string
age: number
}
첫 번째 코드를 보면 user2에서 isAdult 타입 명시를 해주지 않아 오류가 발생했다
해주지 않아도 오류가 나지 않게, 필수가 아닌 타입으로 지정해주기 위해서는 ? 를 사용해주자!
interface IUser {
name: string,
age: number,
isAdult?: boolean // Optional property
}
// `isAdult`를 초기화하지 않아도 에러가 발생하지 않습니다.
let user: IUser = {
name: 'Neo',
age: 123
};
읽기 전용 속성(Readonly properties)
읽기 전용이란 수정이 불가한, 초기화된 값이 그대로 가는 경우다
바꾸려고 하면 오류가 발생한다.
interface IUser {
readonly name: string,
age: number
}
// 초기화
let user: IUser = {
name: 'Neo',
age: 36
};
user.age = 85; // Ok
user.name = 'Evan'; // Error - TS2540: Cannot assign to 'name' because it is a read-only property.
여기서 만약 모든 프로퍼티를 읽기전용으로 만들려고 한다면 유틸리티(Utility)나 단언(Assertion) 타입을 활용하여 한번에 읽기전용으로 만들어줄 수 있다!!
// All readonly properties
interface IUser {
readonly name: string,
readonly age: number
}
let user: IUser = {
name: 'Neo',
age: 36
};
user.age = 85; // Error
user.name = 'Evan'; // Error
// Readonly Utility
interface IUser {
name: string,
age: number
}
let user: Readonly<IUser> = {
name: 'Neo',
age: 36
};
user.age = 85; // Error
user.name = 'Evan'; // Error
// Type assertion
let user = {
name: 'Neo',
age: 36
} as const;
user.age = 85; // Error
user.name = 'Evan'; // Error
함수 타입
만약 함수를 인터페이스로 정의하는 경우 호출 시그니처(Call signature)라는 것을 사용
호출 시그니처는 함수의 매개변수와 return 타입을 지정
interface IName {
(PARAMETER: PARAM_TYPE): RETURN_TYPE // Call signature
}
interface IUser {
name: string
}
//함수 인터페이스 정의
interface IGetUser {
(name: string): IUser
}
// 매개 변수 이름이 인터페이스와 일치할 필요가 없습니다.
// 또한 타입 추론을 통해 매개 변수를 순서에 맞게 암시적 타입으로 제공할 수 있습니다.
const getUser: IGetUser = function (name: string) { // n is name: string
// Find user logic..
// ...
return user;
};
getUser('Heropy');
클래스 타입
인터페이스로 클래스를 정의하는 경우 implements 키워드를 사용
// 인터페이스의 정의
interface ITodo {
id: number;
content: string;
completed: boolean;
}
// Todo 클래스는 ITodo 인터페이스를 구현하여야 한다.
class Todo implements ITodo {
constructor (
public id: number,
public content: string,
public completed: boolean
) { }
}
const todo = new Todo(1, 'Typescript', false);
console.log(todo);
인터페이스를 구현하는 클래스는 인터페이스에서 정의한 프로퍼티와 추상 메소드를 반드시 구현하여야 한다!
// 인터페이스의 정의
interface IPerson {
name: string;
sayHello(): void;
}
/*
인터페이스를 구현하는 클래스는 인터페이스에서 정의한 프로퍼티와 추상 메소드를 반드시 구현하여야 한다.
*/
class Person implements IPerson {
// 인터페이스에서 정의한 프로퍼티의 구현
constructor(public name: string) {}
// 인터페이스에서 정의한 추상 메소드의 구현
sayHello() {
console.log(`Hello ${this.name}`);
}
}
function greeter(person: IPerson): void {
person.sayHello();
}
const me = new Person('Lee');
greeter(me); // Hello Lee
인덱싱 기능 타입(Indexable types)
인터페이스를 통해 프로퍼티의 타입 지정이 가능하긴하지만 수많은 속성을 가지거나 당장 정할 수 없는 임의의 속성이 포함되어 있는 구조에서는 한계를 가진다. 이때 유용하게 쓰이는 것이 바로 인덱싱 기능 타입!!
인덱싱 기능 타입을 정의하는 인터페이스는 인덱스 시그니처를 가질 수 있다.
***arr[2] -> 숫자로 인덱싱 / obj['name'] -> 문자로 인덱싱
인덱스 시그니처는 인덱싱에 사용할 인덱서의 이름과 티입 그리고 인덱싱 결과의 반환 값을 지정 가능
*** 인덱서 타입은 string과 number 만 지정 가능!
interface INAME {
[INDEXER_NAME: INDEXER_TYPE]: RETURN_TYPE // Index signature
}
코드의 예로 확인하자!!
interface IItem {
[itemIndex: number]: string // Index signature
}
let item: IItem = ['a', 'b', 'c']; // Indexable type
console.log(item[0]); // 'a' is string.
console.log(item[1]); // 'b' is string.
console.log(item['0']); // Error - TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
위 코드를 설명하자면
인터페이스 IItem은 인덱스 시그니처를 가지고 있다. 이 인터페이스를 가지는 item이 있다.
이 item을 item[0]과 같이 숫자로 인덱싱할 때 반환하는 값은 문자여야 한다.
interface IItem {
[itemIndex: number]: string | boolean | number[]
}
let item: IItem = ['Hello', false, [1, 2, 3]];
console.log(item[0]); // Hello
console.log(item[1]); // false
console.log(item[2]); // [1, 2, 3]
아래는 문자로 인덱싱을 하는 예제!
interface IUser {
[userProp: string]: string | boolean
}
let user: IUser = {
name: 'Neo',
email: 'thesecon@gmail.com',
isValid: true,
0: false
};
console.log(user['name']); // 'Neo' is string.
console.log(user['email']); // 'thesecon@gmail.com' is string.
console.log(user['isValid']); // true is boolean.
console.log(user[0]); // false is boolean
console.log(user[1]); // undefined
console.log(user['0']); // false is boolean
interface IUser {
[userProp: string]: string | number
name: string,
age: number
}
let user: IUser = {
name: 'Neo',
age: 123,
email: 'thesecon@gmail.com',
isAdult: true // Error - TS2322: Type 'true' is not assignable to type 'string | number'.
};
console.log(user['name']); // 'Neo'
console.log(user['age']); // 123
console.log(user['email']); // thesecon@gmail.com
인터페이스 확장
인터페이스도 클래스처럼 extends 키워드를 활용해 상속할 수 있다.
interface IAnimal {
name: string
}
interface ICat extends IAnimal {
meow(): string
}
class Cat implements ICat { // Error - TS2420: Class 'Cat' incorrectly implements interface 'ICat'. Property 'name' is missing in type 'Cat' but required in type 'ICat'.
meow() {
return 'MEOW~'
}
}
같은 이름의 인터페이스를 여러 개 만들기도 가능!
=> 기존에 만들어진 인터페이스에 내용을 추가하는 경우에 유용
interface IFullName {
firstName: string,
lastName: string
}
interface IFullName {
middleName: string
}
const fullName: IFullName = {
firstName: 'Tomas',
middleName: 'Sean',
lastName: 'Connery'
};
출처
https://poiemaweb.com/typescript-interface
TypeScript - Interface | PoiemaWeb
인터페이스는 일반적으로 타입 체크를 위해 사용되며 변수, 함수, 클래스에 사용할 수 있다. 인터페이스는 여러가지 타입을 갖는 프로퍼티로 이루어진 새로운 타입을 정의하는 것과 유사하다.
poiemaweb.com
goorm
구름은 클라우드 기술을 이용하여 누구나 코딩을 배우고, 실력을 평가하고, 소프트웨어를 개발할 수 있는 클라우드 소프트웨어 생태계입니다.
www.goorm.io
'Typescript' 카테고리의 다른 글
[타입스크립트]Optional - 매개변수, 속성과 메소드, 체이닝, 널 병합 연산자 (0) | 2022.04.10 |
---|---|
[타입스크립트] 제네릭(Generic) (0) | 2022.04.08 |
[타입스크립트]타입 추론(Inference)과 타입 단언(Assertions) (0) | 2022.04.06 |
[타입스크립트] Void, Never , Union , Intersection ,Function (0) | 2022.04.06 |
[타입스크립트] Void, Never , Union , Intersection ,Function (0) | 2022.04.06 |