interface
•
타입이랑 비슷함 (타입 체크를 위해 사용)
•
상호 간에 정의한 약속 혹은 규칙을 의미
•
just 객체의 모양을 TS에게 알려주기 위해 사용
•
직접 인스턴스를 생성할 수 없고 모든 메서드가 추상 메서드이다.
사용이유
•
타입의 이름을 짓고 코드 안의 계약을 정의
•
프로젝트 외부에서 사용하는 코드의 계약을 정의하는 강력한 방법
◦
객체의 스펙(속성과 속성의 타입)
◦
함수의 파라미터
◦
함수의 스펙(파라미터, 반환 타입 등)
◦
배열과 객체에 접근하는 방식
◦
클래스
프로퍼티
•
컴파일러가 검사하는 프로퍼티의 두 가지 요소
◦
필수요소 프로퍼티의 유무
◦
프로퍼티 타입
•
예약어로 프로퍼티를 세밀하게 컨트롤 가능
◦
? : Optional Properties
◦
readonly : 읽기 전용
type Team = "red" | "blue" | "yellow"
type Health = 1 | 3 | 5
interface Player {
nickname: string,
readonly team: Team, //읽기전용 프로퍼티
health?: Health //선택적 프로퍼티
}
function createSquare(config: Player): { color: string; area: number } {
let newSquare = {color: "white", area: 100};
if (config.clor) {
// Error: Property 'clor' does not exist on type 'SquareConfig'
newSquare.color = config.clor;
}
if (config.width) {
newSquare.area = config.width * config.width;
}
return newSquare;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // 오류!
TypeScript
복사
선택적 프로퍼티
•
프로퍼티 선언 시 이름 끝이 ?를 붙여서 사용
읽기 전용
•
프로퍼티 선언 시 이름 앞에 readonly를 붙여서 사용
readonly VS const
•
변수는 const를 사용 권장
•
프로퍼티는 readonly를 사용 권장
인터페이스 상속
interface User {
name: string;
}
interface Player extends User {
}
//type
type User = {
name: string;
}
type Player = User & {
}
TypeScript
복사
중첩
•
인터페이스는 중첩 가능
interface User {
name: string;
}
interface User {
age: number;
}
interface User {
health: number;
}
const honey: User = {
name: "honey",
age: 23,
health: 15
}
TypeScript
복사
interface 상속
interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
interface Human {
health: number;
}
class Player implements User, Human { // 다중 상속 가능
constructor(
public firstName: string,
public lastName: string,
public health: number
){}
fullName() {
return `${this.firstName} ${this.lastName}`
}
sayHi(name: string) {
return `Hello ${name} my name is ${this.fullName()}`
}
}
TypeScript
복사
•
interface는 JS로 변환되지 않기에 추상 클래스보다 가벼움
interface 타입
•
타입스크립트에서 인터페이스 함수, 클래스에서 사용할 수 있다.
함수
•
JS객체가 가질 수 있는 넓은 범위의 형태를 기술한다.
•
프로퍼티로 객체를 기술하는 것 외에도, 인터페이스는 함수 타입을 설명한다.
interface SEarchFunc {
(source: string, subString: string): boolean
}
// 변수로 직접 함수 값이 할당되었기 때문에 인수 타입 생략 가능
// TS의 문맥상 타이핑(contextual typing)이 인수 타입 추론
let mySearch: SEarchFunc
mySearch = function(src, sub) {
let result = src.search(sub);
return result > -1;
}
// error : Type '(src: string, sub: string) => string' is not assignable to type 'SEarchFunc'. Type 'string' is not assignable to type 'boolean'
mySearch = function(src, sub) {
let result = src.search(sub);
return 'string';
}
JavaScript
복사
•
함수의 인자의 타입과 반환 값의 타입을 정의한다.
•
함수의 타입을 정의할 때에도 사용된다.
클래스
•
클래스가 특정 통신 프로토콜을 충족하도록 명시적으로 강제한다.
•
C#과 Java와 같은 언어에서 일반적으로 인터페이스를 사용하는 방법과 동일하다.
// 인터페이스의 정의
interface ITodo {
id: number;
content: string;
completed: boolean;
makeSound(): void
}
// Todo 클래스는 ITodo 인터페이스를 구현하여야 한다.
class Todo implements ITodo {
constructor (
public id: number,
public content: string,
public completed: boolean
) { }
makeSound(): void {
console.log("멍멍")
}
}
const todo = new Todo(1, 'Typescript', false);
console.log(todo);
/*
Todo: {
"id": 1,
"content": "Typescript",
"completed": false
}
*/
console.log(todo.makeSound()); // 멍멍
JavaScript
복사
•
클래스가 특정 계약(contract)을 충족하도록 명시적으로 강제한다.
•
클래스 선언문의 implements 뒤에 인터페이스를 선언하면 해당 클래스는 지정된 인터페이스를 반드시 구현하여야 한다.
•
이는 인터페이스를 구현하는 클래스의 일관성을 유지할 수 있는 장점을 갖는다.
•
인터페이스는 프로퍼티와 메서드를 가질 수 있다는 점에서 클래스와 유사하나 직접 인스턴스를 생성할 수는 없다.
interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
function makeUser(user: User): User {
return {
firstName: "honey",
lastName: "bee",
fullName: () => "xx",
sayHi: (name) => "ss"
}
}
makeUser({
firstName: "honey",
lastName: "bee",
fullName: () => "xx",
sayHi: (name) => "ss"
})
TypeScript
복사
hybrid type
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = function (start: number) {} as Counter;
counter.interval = 123;
counter.reset = function () {};
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
JavaScript
복사
•
자바스크립트의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러 타입을 조합 가능
•
위 코드와 같이 함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스도 구현 가능
Interface 활용 디자인 패턴
객체가 할 수 있는 행위들을 전략(strategy)으로 만들어두고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것만으로 수정이 가능하도록 만든 패턴
class VendingMachine {
pay() {
console.log("cash pay!");
}
}
// 전략 패턴 도입
interface PaymentStrategy {
pay(): void;
}
class CardPaymentStrategy implements PaymentStrategy {
pay(): void {
console.log("card pay!");
}
}
class CashPaymentStrategy implements PaymentStrategy {
pay(): void {
console.log("Cash pay!");
}
}
class VendingMachine {
private paymentStrategy: PaymentStrategy;
setPaymentStrategy(paymentStrategy: PaymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
pay() {
this.paymentStrategy.pay();
}
}
const vendingMachine =new VendingMachine();
vendingMachine.setPaymentStrategy(new CashPaymentStrategy());
vendingMachine.pay(); // cash pay
vendingMachine.setPaymentStrategy(new CardPaymentStrategy());
vendingMachine.pay(); // card pay
TypeScript
복사