728x90
반응형
인터페이스
- 타입이랑 비슷함 (타입 체크를 위해 사용)
- 상호 간에 정의한 약속 혹은 규칙을 의미
- 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; // 오류!
선택적 프로퍼티
- 프로퍼티 선언 시 이름 끝이 ?를 붙여서 사용
읽기 전용
- 프로퍼티 선언 시 이름 앞에 readonly를 붙여서 사용
readonly VS const
readonly와 const 중에 어떤 것을 사용할 지 기억하기 가장 쉬운 방법은 변수와 프로퍼티중 어디에 사용할지 질문해 보는 것이다. 변수는 const를 사용하고 프로퍼티는 readonly를 사용하는 것을 권장한다.
인터페이스 상속
interface User {
name: string;
}
interface Player extends User {
}
//type
type User = {
name: string;
}
type Player = User & {
}
중첩
- 인터페이스는 중첩 가능
interface User {
name: string;
}
interface User {
age: number;
}
interface User {
health: number;
}
const honey: User = {
name: "honey",
age: 23,
health: 15
}
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()}`
}
}
- 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';
}
- 함수의 인자의 타입과 반환 값의 타입을 정의한다.
- 함수의 타입을 정의할 때에도 사용된다.
클래스
- 클래스가 특정 통신 프로토콜을 충족하도록 명시적으로 강제한다.
- 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()); // 멍멍
- 클래스가 특정 계약(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"
})
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;
- 자바스크립트의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러 타입을 조합 가능
- 위 코드와 같이 함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스도 구현 가능
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
하이브리드 타입
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;
참고
반응형
'언어 > TypeScript' 카테고리의 다른 글
클래스 (0) | 2023.10.30 |
---|---|
함수 (1) | 2023.10.30 |
타입 명시 (1) | 2023.10.29 |
설정 (0) | 2023.10.29 |
TypeScript란? (0) | 2023.10.29 |