// 아주 간단한 예시의 인터페이스 사용 예제
interface Person1 {
name: string;
age: number;
}
function sayHi(person: Person1): void {
console.log(`안녕 나는 ${person.name} 입니다.`);
}
const p1: Person1 = {
name: 'Jinju',
age: 26,
}
sayHi(p1);
프로퍼티가 있을 수도 있고 없을 수도 있을 때
interface Person2 {
name: string;
age?: number; // 물음표를 붙여준다
}
function sayHi2(person: Person2): void {
console.log(`안녕 나는 ${person.name} 입니다.`);
}
hello2({name: 'Jinju', age: 26});
hello2({name: 'pearl'});
interface Person3 {
name: string;
age?: number;
[index: string]: any; // 어떤 프로퍼티가 와도 괜찮다 라는 뜻
}
function hello3(person: Person3): void {
console.log(`안녕! ${person.name} 입니다.`);
}
const p31: Person3 {
name: 'Jinju',
age: 26,
};
const p32: Person3 {
name: 'someone',
example: ['anyone', 'noOne'], // any타입으로 지정했으므로 배열도 올 수 있다
};
const p33: Person3 = {
name: 'pearl',
friend1: p31,
friend2: p32,
};
인터페이스 내부에 함수를 정의하는 법
interface Person4 {
name: string;
age: number;
hello(): void;
}
const p41: Person = {
name: 'Jinju',
age: 26,
hello: function(): void {
console.log(`나는 ${this.name} 입니다.`);
},
};
const p42: Person = {
name: 'Jinju',
age: 26,
hello(): void { // function 키워드를 생략해도 무방
console.log(`나는 ${this.name} 입니다.`);
},
};
const p43: Person = {
name: 'Jinju',
age: 26,
hello: (): void => {
// 화살표 함수를 써도 된다
// 하지만 화살표 함수를 사용하는 경우 this를 사용할 수 없음
// 해당 블록 스코프 안에 가리킬 this가 없기 때문이다
// console.log(`나는 ${this.name} 입니다.`);
},
};
인터페이스를 이용해서 클래스 만들어내기
interface IPerson1 {
name: string;
age?: number;
hello(): void;
}
class Person implements IPerson1 {
// 자동완성으로 생성된다
name: string;
age?: number | undefined;
constructor(name: string) {
// name의 초기값이 없다고 뜨므로 생성자 만들어줌
this.name = name;
}
hello(): void {
// throw new Error("Method not implmented.");
console.log(`안녕! ${this.name} 입니다.`);
}
}
// 클래스도 인터페이스처럼 타입처럼 사용될 수 있다
const person: IPerson1 = new Person('Jinju');
perseon.hello();
대규모 프로젝트 작업 시 인터페이스를 사용해서 상속관계를 이루는 편이 좋다
interface IPerson2 {
name: string;
age?: number;
}
interface IKorean extends IPerson2 {
city: string;
}
const k: IKorean = {
name: '진주',
city: '서울',
};
interface HelloPerson {
(name: string, age?: number): void;
// (인자로 받을 값) : 리턴타입
}
// 구현체는 타이핑에 영향을 미치지 않는다
const helloPerson: HelloPerson = function(name: string) {
console.log(`안녕 ${name} 입니다.`);
}
// helloPerson 인자에 name만 받겠다고 구현했음에도 불구
// HelloPerson 인터페이스가 우선하기 때문에 age를 넣어도 무방
helloPerson('Jinju', 26);
interface Person8 {
name: string;
age?: number;
readonly gender: string;
}
const p81: Person8 = {
name: 'Jinju',
gender: 'female',
};
p81.gender = 'male';
// error! Cannot assign to 'gender' because it is a read-only property
Type Alias- 타입을 부르는 이름
Interface- 타입을 만들어 내는 것
// type alias
type EatType = (food:string) => void;
// interface
interface IEat {
(food: string): void;
}
// type alias
type PersonList = string[];
// interface
interface IPersonList {
[index: number]: string;
}
interface ErrorHandling {
success: boolean;
error?: { message: string };
}
interface ArtistData {
artists: { name: string }[];
}
// type alias
type ArtistResponseType = ArtistData & ErrorHandling;
// interface
// 다중상속을 활용
interface IArtistResponse extends ArtistData, ErrorHandling {}
let art: ArtistResponseType;
let iar: IArtistResponse;
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(); void;
layEggs(); void;
}
// type alias
type petType = Bird | fish;
// interface
// 인터페이스로 구현하기는 어렵다
interface IPet extends PetType {}
// error: An interface can only extend an object type of intersection of object types with statically known members.
// 유니온 타입은 클래스에 implement로 넣어줄 수 없다
class Pet implements PetType {}
// error: A class can only implement an object type of intersection of object types with statically known members.
interface MergingInterface {
a: string;
}
interface MergingInterface {
b: string;
}
let mi: MergingInterface;
mi. // a와 b가 모두 나온다
언제 사용하는가❓
👉 HTML element를 확장 시 기존의 것에 새로운 것을 합치고자 할 때