인터페이스

ujin·2022년 11월 20일
0

TypeScript

목록 보기
4/5

interface

property를 정의해서 객체로 사용하고자 할 때는 interface를 사용한다

const user:object;

user = {  // Cannot assign to 'user' because it is a constant.
    name : 'ujin',
    age: 21
}

console.log(user.name); // Property 'name' does not exist on type 'object'.
interface User {
    name : string,
    age: number;
}

let user : User = {
    name : 'ujin',
    age : 21
}

console.log(user.age)

Interface

인터페이스는 일반적으로 타입 체크를 위해 사용되며 변수, 함수, 클래스에 사용할 수 있다.

여러 가지 타입을 갖는 프로퍼티로 이루어진 새로운 타입을 정의하는 것과 유사하다.

ES6는 인터페이스를 지원하지 않지만 TypeScript는 인터페이스를 지원한다

변수와 인터페이스

인터페이스는 변수의 타입으로 사용할 수 있다. 이때 인터페이스를 타입으로 선언한 변수는 해당 인터페이스를 준수하여야 하고 새로운 타입으로 정의하는 것과 유사하다.

// 인터페이스 정의
interface Ts {
    id: number;
    content: string;
    completed: boolean;
}

// 변수 ts의 타입으로 TS 인터페이스 선언
let ts: Ts;

// 변수 ts는 Ts 인터페이스에 준수해야 한다
ts = {
    id: 1,
    content: 'typescript',
    completed: false
}

인터페이스를 사용하여 함수 파라미터의 타입을 선언할 수 있다. 이때 해당 함수에는 파라미터의 타입으로 지정한 인터페이스를 준수하는 인수를 전달하여야 한다.

// 인터페이스 정의
interface Ts {
    id: number;
    content: string;
    completed: boolean;
}

let tss: Ts[] = [];

// 파라미터 ts의 타입으로 Ts 인터페이스를 선언
function addTs(ts: Ts) {
    tss = [...tss, ts]
}

// 파라미터 ts는 Ts 인터페이스를 준수하여야 한다
const newTs: Ts = {
    id:1,
    content: 'typescript',
    completed: false
}
addTs(newTs);
console.log(tss) // [{ id: 1, content: 'typescript', completed: false }]

함수와 인터페이스

인터페이스는 함수의 타입으로 사용할 수 있다. 이때 함수의 인터페이스에 타입이 선언된 파라미터 리스트와 리턴 타입을 정의한다. 함수 인터페이스를 구현하는 함수는 인터페이스를 준수하여야 한다.

// 함수 인터페이스 정의
interface Foo {
    (num: number): number;
}

// 함수 인터페이스를 구현하는 함수는 인터페이를 준수하여야 한다
const foo: Foo = function (num: number) {
    return num * num;
}

console.log(foo(10))

클래스와 인터페이스 → 이건 나중에 더 알아보기(https://poiemaweb.com/typescript-interface)

클래스 선언문의 implements 뒤에 인터페이스를 선언하면 해당 클래스는 지정된 인터페이스를 반드시 구현하여야 한다. 이는 인터페이스를 구현하는 클래스의 일관성을 유지할 수 있는 장점을 갖는다.

덕 타이핑 (Duck typing)

인터페이스를 구현하는 것이 타입 체크를 통과하는 유일한 방법은 아니다.

타입 체크에서는 값을 실제로 가지고 있는 것이 중요하다.

// 1. 인터페이스 Iduk은 quack 메소드를 정의함
interface Iduk {
    quack(): void;
}

// 3. 클래스 MallardDuck은 인터페이스 Iduk을 구현
class MallardDuck implements Iduk {
    quack() {
        console.log('Quack!');
    }
}

// 4. 클래스 RedheadDuck은 인터페이스 Iduk을 구현하지는 않았지만 quack 메소드를 가짐
**class RedheadDuck {
    quack() {
        console.log('q~uack');
    }
}**

//2. makeNoise 함수는 인터페이스 iduk을 구현한 클래스의 인스턴스 duck을 인자로 받는다
function makeNoise(duck: Iduk): void {
    duck.quack();
}

makeNoise(new MallardDuck()); // Quack!
// 5. makeNoise 함수에 인터페이스 Iduk을 구현하지 않는 클래스 RedheadDuck의 인스턴스를 인자로 전달하여도 에러 없이 처리된다
makeNoise(new RedheadDuck()); //q~uack!

TypeScript는 해당 인터페이스에서 정의한 프로퍼티나 메소드를 가지고 있다면 그 인터페이스를 구현한 것으로 인정한다. 이것을 덕 타이핑 또는 구조적 타이핑이라 한다.

인터페이스를 변수에 사용할 경우에도 덕 타이핑은 적용된다.

interface Name {
    name: string;
}

function foo(person: Name): void {
    console.log(`Hello ${person.name}`);
}

const me = { name: 'ujin', age: '21' }; // 변수 me는 인터페이스 Name과 일치하지 않지만
																				// Name의 name 프로퍼티를 가지고 있어서 인터페이스에 부합하는 것으로 인정된다.
foo(me)

선택적 프로퍼티

인터페이스의 프로퍼티는 반드시 구현되어야 한다. 하지만 인터페이스의 프로퍼티가 선택적으로 필요한 경우가 있을 수 있다. 선택적 프로퍼티는 프로퍼티명 뒤에 ?를 붙이며 생략하여도 에러가 발생하지 않는다.

interface UserInfo {
    username: string;
    password: string;
    age? : number; // 사용하지 않는 프로퍼티
    address?: string;
}

const userInfo: UserInfo = {
    username: 'hong@ddd.com',
    password: '12345'
}

console.log(userInfo);

인터페이스 상속 → class할 때 더 알아보기

인터페이스는 extends 키워드를 사용하여 인터페이스 또는 클래스를 상속받을 수 있다.

interface Person {
  name: string;
  age?: number;
}

interface Student extends Person {
  grade: number;
}

const student: Student =  {
  name: 'Lee',
  age: 20,
  grade: 3
}
profile
개발공부일기

0개의 댓글