TypeScript : 인터페이스와 유형


답변:


572

당으로 타이프 스크립트 언어 사양 :

이름 지정된 객체 유형을 항상 도입하는 인터페이스 선언과 달리 유형 별명 선언 은 기본 유형, 공용체 및 교차 유형을 포함한 모든 유형의 이름을 도입 할 수 있습니다.

사양은 다음과 같이 언급됩니다.

인터페이스 유형 은 객체 유형 리터럴의 유형 별칭과 많은 유사하지만 인터페이스 유형이 더 많은 기능을 제공하므로 일반적으로 별칭을 입력하는 것이 좋습니다. 예를 들어, 인터페이스 유형

interface Point {
    x: number;
    y: number;
}

타입 별칭으로 쓸 수 있습니다

type Point = {
    x: number;
    y: number;
};

그러나 이렇게하면 다음 기능이 손실됩니다.

  • extends 또는 implements 절에서 인터페이스의 이름을 지정할 수 있지만 TS 2.7 이후 로 객체 유형 리터럴의 유형 별명이 더 이상 참일 수 없습니다 .
  • 인터페이스는 여러 개의 병합 선언을 가질 수 있지만 객체 유형 리터럴의 유형 별명은 사용할 수 없습니다.

109
"다중 병합 선언"은 두 번째 차이점에서 무엇을 의미합니까?
jrahhali

66
@jrahhali 인터페이스를 두 번 정의하면 typescript가 인터페이스를 하나로 병합합니다.
Andrey Fedorov

39
@jrahhali 타입을 두 번 정의하면 typescript에서 오류가 발생합니다
Andrey Fedorov

18
@jrahhaliinterface Point { x: number; } interface Point { y: number; }
Nahuel Greco

20
첫 번째 요점 extends or implements이 더 이상 그렇지 않다고 생각 합니다. 유형은로 확장하고 구현할 수 있습니다 class. 다음은 typescriptlang.org/play/…
dark_ruby

774

2019 년 업데이트


현재 답변과 공식 문서 는 구식입니다. 그리고 TypeScript를 처음 사용하는 사람들에게는 사용 된 용어가 예제없이 명확하지 않습니다. 아래는 최신 차이점 목록입니다.

1. 객체 / 기능

둘 다 객체의 모양이나 함수 서명을 설명하는 데 사용할 수 있습니다. 그러나 구문이 다릅니다.

상호 작용

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

유형 별명

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

2. 다른 유형

인터페이스와 달리, 유형 별명은 기본 요소, 공용체 및 튜플과 같은 다른 유형에도 사용될 수 있습니다.

// primitive
type Name = string;

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

3. 연장

둘 다 확장 할 수 있지만 구문은 다릅니다. 또한 인터페이스와 유형 별칭은 상호 배타적이지 않습니다. 인터페이스는 유형 별명을 확장 할 수 있으며 그 반대도 가능합니다.

인터페이스 확장 인터페이스

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

타입 별칭은 타입 별칭을 확장합니다

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

유형 별명을 확장하는 인터페이스

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

유형 별명은 인터페이스를 확장

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

4. 구현

클래스는 인터페이스 또는 유형 별칭을 동일한 방식으로 구현할 수 있습니다. 그러나 클래스와 인터페이스는 정적 청사진으로 간주됩니다. 따라서 통합 유형의 이름을 지정하는 유형 별명을 구현 / 확장 할 수 없습니다.

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

5. 선언 병합

유형 별명과 달리 인터페이스는 여러 번 정의 될 수 있으며 단일 선언으로 취급됩니다 (모든 선언의 멤버가 병합 됨).

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };

9
공식 문서가 구식 인 경우 제공 한 정보를 어디서 확인할 수 있습니까?
iX3

59
이 게시물을 기반으로 유형 별칭 대신 인터페이스를 선택하는 유일한 이유는 인터페이스의 선언 병합 (포인트 5) 기능을 사용하려는 것입니다. 그 외에도 그것들은 동등합니다 (그리고 타입 별칭이 더 간결한 구문을 제공한다고 주장합니다).
maxedison 2019

17
나는 항상 객체 유형 리터럴에 인터페이스를 사용합니다. 그렇지 않으면 유형을 사용하는 것이 더 의미가 있습니다. 어쨌든 선언 병합을 사용해서는 안된다고 생각합니다. 실제로 인터페이스가 프로젝트의 다른 파일에서 일부 파일과 함께 선언되는 것을 기대하지 않습니다. 추가 속성, 유형 검사는 원래이 닌자 같은 인터페이스를 사용하여 더 힘들게 만들지 않도록하기 위해 만들어졌습니다. D
Ahmed Kamal

8
기본적으로, 우리가 실제로 편안하게 느끼는 것에 대해 "거의 개인적인"선택입니까? 한 가지 이유 외에도, 당신은 type또는 interface? 나는 하나 또는 다른 것을 사용해야 할 때 여전히 혼란 스럽습니다.
Joseph Briggs

7
누군가 인터페이스 병합을 원하는 이유에 대한 동기 부여를 해 주시겠습니까? 잠재적으로 혼란스러워 보입니다. 왜 인터페이스 정의를 다른 블록에 분산시키고 싶습니까?
Vanquish46

95

TypeScript 3.2 (2018 년 11 월) 기준으로 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


9
제공 한 테이블 / 이미지 생성 방법에 대한 자세한 정보를 제공해 주시겠습니까? 예 : 소스 코드 또는 문서 링크
iX3

23
예, 프레젠테이션의 내용이 아니라 내용의 출처를 의미했습니다.
iX3

3
클래스 가 유형이나 인터페이스를 확장 할 수 있다고 생각하지 않으며 왜 당신이 원하는지 알 수 없습니다 ??
Dan King

7
텍스트 이미지를 게시하지 말고 실제 텍스트를 게시물에 직접 포함하십시오. 텍스트 이미지는 쉽게 구문 분석하거나 검색 할 수 없으며 시각 장애가있는 사용자가 액세스 할 수 없습니다.
앤드류 마샬

2
이 테이블에는 그 내용을 뒷받침 할만한 자료가 없기 때문에 의존하지 않습니다. 예를 들어, type특정 제한을 사용하여 재귀 유형을 정의 할 수 있습니다 (TypeScript 3.7부터 이러한 제한도 사라짐). 인터페이스는 유형을 확장 할 수 있습니다. 클래스는 유형을 구현할 수 있습니다. 또한, 데이터를 테이블의 스크린 샷으로 표시하면 시각 장애가있는 사용자가 완전히 액세스 할 수 없습니다.
Michał Miszczyszyn


5

유형이있는 예 :

// 객체의 트리 구조를 만듭니다. 교차로가 없기 때문에 인터페이스에서 동일한 작업을 수행 할 수 없습니다 (&)

type Tree<T> = T & { parent: Tree<T> };

// 몇 가지 값만 할당하도록 변수를 제한하려면 입력하십시오. 인터페이스에는 공용체가 없습니다 (|)

type Choise = "A" | "B" | "C";

// 유형 덕분에 조건부 메커니즘 덕분에 NonNullable 유형을 선언 할 수 있습니다.

type NonNullable<T> = T extends null | undefined ? never : T;

인터페이스 예제 :

// OOP에 인터페이스를 사용하고 '구현물'을 사용하여 객체 / 클래스 골격을 정의 할 수 있습니다.

interface IUser {
    user: string;
    password: string;
    login: (user: string, password: string) => boolean;
}

class User implements IUser {
    user = "user1"
    password = "password1"

    login(user: string, password: string) {
        return (user == user && password == password)
    }
}

// 다른 인터페이스로 인터페이스를 확장 할 수 있습니다

    interface IMyObject {
        label: string,
    }

    interface IMyObjectWithSize extends IMyObject{
        size?: number
    }


-2

문서는 설명했다

  • 한 가지 차이점은 인터페이스가 모든 곳에서 사용되는 새로운 이름을 생성한다는 것입니다. 유형 별칭은 새 이름을 만들지 않습니다. 예를 들어 오류 메시지는 별칭 이름을 사용하지 않습니다. 이전 버전의 TypeScript에서는 유형 별칭을 확장하거나 구현할 수 없었습니다 (다른 유형을 확장 / 구현할 수도 없음). 버전 2.7부터 새로운 교차 유형을 작성하여 유형 별명을 확장 할 수 있습니다.
  • 반면에 인터페이스로 모양을 표현할 수없고 공용체 또는 튜플 형식을 사용해야하는 경우 일반적으로 형식 별칭이 사용됩니다.

인터페이스 대 유형 별명

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.