TypeScript에서 인터페이스 파일 정의를 기반으로 객체를 만들려면 어떻게해야합니까?


313

다음과 같은 인터페이스를 정의했습니다.

interface IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
 }

다음과 같은 변수를 정의합니다.

var modal: IModal;

그러나 모달의 속성을 설정하려고하면 다음과 같은 메시지가 나타납니다.

"cannot set property content of undefined"

인터페이스를 사용하여 모달 객체를 설명해도됩니까? 그렇다면 어떻게 만들어야합니까?

답변:


426

다른 곳에서 "modal"변수를 작성하고 TypeScript에 모든 작업을 수행하려면 다음을 사용하십시오.

declare const modal: IModal;

실제로 TypeScript에서 IModal의 인스턴스가 될 변수를 만들려면 변수를 완전히 정의해야합니다.

const modal: IModal = {
    content: '',
    form: '',
    href: '',
    $form: null,
    $message: null,
    $modal: null,
    $submits: null
};

또는 형식 어설 션을 사용하여 거짓말을하지만 액세스 할 때 예기치 않은 장소에서 정의되지 않고 런타임 오류가 발생할 수 modal.content있으므로 유형 안전이 손실 됩니다 (계약서에 명시된 속성).

const modal = {} as IModal;

예제 클래스

class Modal implements IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
}

const modal = new Modal();

당신은 "이것은 인터페이스의 중복이라고 생각합니다."라고 생각할 수도 있습니다. Modal 클래스가 IModal 인터페이스의 유일한 구현이라면 인터페이스를 모두 삭제하고 사용할 수 있습니다 ...

const modal: Modal = new Modal();

오히려

const modal: IModal = new Modal();

2
감사. 처음에 모든 모달 내용을 정의하지 않아도되기를 바랐습니다. 인터페이스 대신 Modal을 속성이있는 클래스로 정의 한 다음 new 및 생성자를 사용하여 모든 초기 값을 설정하면 더 쉬울까요?

1
예. 클래스를 정의한 다음 필요할 때만 새 인스턴스를 작성하면됩니다. 예가 필요하십니까?
Fenton

2
인터페이스에 대한 예제와 메모를 추가했습니다.
Fenton

21
var modal = <IModal>{};이것은 내가 찾던 것입니다 ;-) 감사합니다!
Legends

5
참고로, {} as IModal대신 에 사용하는 것이 좋습니다 <IModal>{}. <foo>JSX에서 스타일 어설 션을 사용할 때 언어 문법의 모호성을 제거합니다 . 더 읽어보십시오 . 물론 let이나 const대신에을 사용하십시오 var.
Alex Klaus

191

인터페이스의 빈 객체를 원한다면 다음을 수행하십시오.

var modal = <IModal>{};

데이터를 구조화하기 위해 클래스 대신 인터페이스를 사용하면 클래스에 메소드가없는 경우 컴파일 된 JS에 빈 메소드로 표시됩니다. 예:

class TestClass {
    a: number;
    b: string;
    c: boolean;
}

컴파일

var TestClass = (function () {
    function TestClass() {
    }
    return TestClass;
})();

그것은 가치가 없다. 반면 인터페이스는 데이터 구조화 및 유형 검사의 이점을 제공하면서 JS에 전혀 표시되지 않습니다.


1
`위의 의견을 추가합니다. "updateModal (IModal modalInstance) {}"함수를 호출하려면 다음과 같이 인터페이스 'IModal'의 인라인 인스턴스를 만들 수 있습니다. // 여기에서 updateModal 함수 및 IModal에 액세스 할 수있는 일부 코드 : updateModal (<IModal> {//이 줄은 인스턴스 내용을 만듭니다 : '', 형식 : '', href : '', $ form : null, $ message : null, $ modal : null, $ submits : null}); // 코드를 완성합니다
Sunny

사용하여 var modal= <abc>{}빈 객체의 abc 유형의 모달을 할당했지만 모달의 유형을 선언했습니다. typescript6을 사용하고 있습니다.
Pardeep Jain이

이것은 받아 들일 수없는 대답에 명시된 것처럼 전체 객체를 초기화해야했습니다.
Rahul Sonwanshi


22

기본적으로 다섯 가지 옵션 이 있다고 생각합니다 . 달성하고자하는 목표에 따라 그 중에서 선택하는 것이 쉬울 수 있습니다.

TypeScript를 사용하여 형식 검사를 적용하기 때문에 대부분의 경우 클래스사용하고 인스턴스화하는 가장 좋은 방법입니다 .

interface IModal {
    content: string;
    form: string;
    //...

    //Extra
    foo: (bar: string): void;
}

class Modal implements IModal {
    content: string;
    form: string;

    foo(param: string): void {
    }
}

다른 방법으로 인터페이스에서 객체를 생성하는 더 쉬운 방법을 제공하더라도 다른 문제에 객체를 사용하는 경우 인터페이스를 분리하는 것이 좋습니다. 인터페이스가 과도하게 분리되지 않습니다.

interface IBehaviour {
    //Extra
    foo(param: string): void;
}

interface IModal extends IBehaviour{
    content: string;
    form: string;
    //...
}

반면에, 예를 들어 코드를 단위 테스트하는 동안 (문제 분리를 자주 적용하지 않을 경우) 생산성을 위해 단점을 수용 할 수 있습니다. 주로 큰 타사 * .d.ts 인터페이스에 대한 모의 객체를 만들기 위해 다른 방법을 적용 할 수 있습니다. 그리고 모든 거대한 인터페이스에 대해 항상 익명의 객체를 구현하는 것은 고통 스러울 수 있습니다.

이 경로에서 첫 번째 옵션은 빈 객체만드는 것입니다 .

 var modal = <IModal>{};

둘째 , 인터페이스의 필수 부분완전히 실현하십시오 . 타사 JavaScript 라이브러리를 호출하는지 여부에 유용 할 수 있지만 이전과 같이 클래스를 대신 만들어야한다고 생각합니다.

var modal: IModal = {
    content: '',
    form: '',
    //...

    foo: (param: string): void => {
    }
};

셋째 , 인터페이스일부만 만들고 익명의 개체를 만들 수 있지만이 방법으로 계약을 이행해야합니다.

var modal: IModal = <any>{
    foo: (param: string): void => {

    }
};

인터페이스가 JavaScript 코드로 변환되지 않기 때문에 인터페이스가 선택 사항이더라도 내 대답을 요약하면 TypeScript는 현명하고 일관되게 사용되는 경우 새로운 수준의 추상화를 제공합니다. 나는 당신이 자신의 코드에서 대부분의 경우에 그것들을 기각 할 수 있다고 생각해서는 안됩니다.



12

상단에서 동등한 답변을 찾지 못했기 때문에 답변이 다릅니다. 나는한다:

modal: IModal = <IModal>{}

2

당신의 인터페이스를 사용하여 할 수 있습니다

class Modal() {
  constructor(public iModal: IModal) {
   //You now have access to all your interface variables using this.iModal object,
   //you don't need to define the properties at all, constructor does it for you.
  }
}

2

다른 접근 방식은 다음과 같습니다.

이와 같이 ESLint 친화적 인 객체를 간단하게 만들 수 있습니다

const modal: IModal = {} as IModal;

또는 인터페이스를 기반으로하는 기본 인스턴스와 적절한 기본값이있는 경우

const defaultModal: IModal = {
    content: "",
    form: "",
    href: "",
    $form: {} as JQuery,
    $message: {} as JQuery,
    $modal: {} as JQuery,
    $submits: {} as JQuery
};

그런 다음 단순히 일부 속성을 재정 의하여 기본 인스턴스의 변형

const confirmationModal: IModal = {
    ...defaultModal,     // all properties/values from defaultModal
    form: "confirmForm"  // override form only
}

1

지금까지 게시 된 많은 솔루션은 유형 어설 션을 사용하므로 구현시 필요한 인터페이스 속성이 생략 된 경우 컴파일 오류가 발생하지 않습니다.

다른 강력하고 컴팩트 한 솔루션에 관심이있는 사용자 :

옵션 1 : 인터페이스를 구현하는 익명 클래스를 인스턴스화하십시오.

new class implements MyInterface {
  nameFirst = 'John';
  nameFamily = 'Smith';
}();

옵션 2 : 유틸리티 기능 생성 :

export function impl<I>(i: I) { return i; }

impl<MyInterface>({
  nameFirst: 'John';
  nameFamily: 'Smith';
})

0

을 사용하여 기본값을 설정할 수 있습니다 Class.

클래스 생성자가없는 경우 :

interface IModal {
  content: string;
  form: string;
  href: string;
  isPopup: boolean;
};

class Modal implements IModal {
  content = "";
  form = "";
  href: string;  // will not be added to object
  isPopup = true;
}

const myModal = new Modal();
console.log(myModal); // output: {content: "", form: "", isPopup: true}

클래스 생성자

interface IModal {
  content: string;
  form: string;
  href: string;
  isPopup: boolean;
}

class Modal implements IModal {
  constructor() {
    this.content = "";
    this.form = "";
    this.isPopup = true;
  }

  content: string;

  form: string;

  href: string; // not part of constructor so will not be added to object

  isPopup: boolean;
}

const myModal = new Modal();
console.log(myModal); // output: {content: "", form: "", isPopup: true}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.