클래스 내부 열거 (TypeScript 정의 파일)


83

나는 주변을 수색했지만 이것에 대한 답을 찾을 수없는 것 같습니다. 당신이 도울 수 있기를 바랍니다. 이미지에 열거 형을 추가하려면 어떻게해야합니까? 이것은 내가 이상적으로 바라는 것이지만 오류가 발생합니다.

declare module 'Lib' {

  export module Graphics {

    export class Image {

      enum State {}

      static STATE_IDLE: State;
      static STATE_LOADING: State;
      static STATE_READY: State;
      static STATE_ERROR: State;

      constructor();

    }

  }

}

State를 Graphics 모듈로 이동하면 작동하지만 이제 State가 Graphics에 속하므로 올바르지 않습니다. 이미지의 일부 여야합니다.

답변:


64

다음은 KoenT 솔루션의 개선이라고 생각합니다.

export class Image
{
    constructor ()
    {
        this.state = Image.State.Idle;
    }

    state: Image.State;
}

export namespace Image
{
    export enum State
    {
        Idle,
        Loading,
        Ready,
        Error
    }
}

명명 된 가져 오기를 활용할 수 있다는 장점은 다음과 같습니다.

import {Image} from './image';
let img = new Image()
img.state = Image.State.Error

4
이 기술은 Declaration Merging 의 공식 참조에도 설명되어 있습니다. 이 기술을 사용하려면 export default, 하나는 제거 할 export에서 키워드를 classnamespace하고 줄을 추가 export default Image;의 닫기 괄호 후 namespace.
zett42

답변 해 주셔서 감사합니다! 이 선언문의 병합에 대해서는 아직 몰랐습니다. 와우, 강력합니다!
Janis Jansen

더 이상 작동하지 않습니다. 오류 : '네임 스페이스'및 '모듈'은 허용되지 않습니다 (네임 스페이스 없음). typescriptlang.org/docs/handbook/…
Shadoweb

@Shadoweb 이것은 확실히 작동합니다 ... "no-namespace"오류는 ts-lint 구성 (논란의 여지가있는 구성)이며 타이프 스크립트 오류가 아닙니다. 참조 palantir.github.io/tslint/rules/no-namespacegithub.com/microsoft/TypeScript/issues/30994
NSjonas

1
작동하지 않는, 당신은 .... 클래스 자체, 어떤 부하 내부의 열거를 사용할 수 없습니다
phil123456

41

여기 내 해결책이 있습니다.

program.ts :

enum Status {
    Deleting,
    Editing,
    Existing,
    New
}

export class Program {
    static readonly Status = Status;
    readonly Status = Program.Status;

    title: string;

    status: Status;

    constructor(init?: Partial<Program>) {
        Object.assign(this, init);
    }
}

용법:

let program = new Program({ title: `some title` });

program.status = Program.Status.New;

또는

program.status = program.Status.New;

Angular 2+ 사용자를위한 추가 혜택 : 템플릿에서 사용할 수 있습니다.

<div *ngIf="program.status === program.Status.New">
  Only display if status of the program is New
</div>

2
좋은 접근 방식이지만 열거 형 유형의 변수를 선언해야하는 경우 어떻게해야합니까? enumVar: Program.Status;작동하지 않는
Dimanoid

1
이것이 허용되는 솔루션이어야하며 다른 솔루션은 lint 경고를 생성합니다 ( github.com/bradzacher/eslint-plugin-typescript/blob/master/docs/… )
graup

static템플릿이 해당 구성 요소의 정적 속성을 사용할 수 없기 때문에 를 제거하지 않으면 Angular에서 작동하지 않습니다.
허치 무어

따라서 readonly Status = Program.Status;바로 아래 static.
Mažvydas Tadaravičius 2011

38

나는 또한 최근에이 문제에 부딪혔다. 이것이 제가 현재 해결책으로 사용하고있는 것입니다.

// File: Image.ts

class Image
{
    constructor()
    {
        this.state = Image.State.Idle;
    }

    state: Image.State;
}

module Image
{
    export enum State
    {
        Idle,
        Loading,
        Ready,
        Error
    }
}

export = Image;

그런 다음 클래스와 열거 형을 사용하는 곳에서 :

import Image = require("Image");

let state = Image.State.Idle;
let image = new Image();
state = image.state;

이것은 잘 작동하는 것 같습니다 (이런 종류의 일을 예상하는 방법으로 생각하지 않더라도).

바라건대 TypeScript에 이런 식으로 할 수있는 방법이있을 것입니다 :

class Image
{
    enum State
    {
        Idle,
        Loading,
        Ready,
        Error
    }

    constructor()
    {
        this.state = State.Idle;
    }

    state: State;
}

export = Image;

3

모듈 확대를 사용하는이 작업은 작업을 수행하는 매우 해키하고 직관적이지 않은 방법 *이라고 생각하므로 다음을 고려하십시오.

export module Graphics
{
    enum State
    {
        STATE_IDLE,
        STATE_LOADING,
        STATE_READY,
        STATE_ERROR
    }

    export class Image
    {
        constructor() { }
        public static readonly State = State;
    }
}

//...

let imgState = Graphics.Image.State.STATE_ERROR;

즉, 내 보내지 않고 추가하려는 클래스의 범위에서 열거 형을 선언 한 다음 클래스의 멤버를 통해 노출합니다.

* 기술적으로 작동하더라도 코드의 구조 및 구성과 관련하여 BAD입니다.

최신 정보

declare module Lib
{
    enum State
    {
        STATE_IDLE,
        STATE_LOADING,
        STATE_READY,
        STATE_ERROR
    }

    class ImageClass
    {
        constructor();
        public Prop: any;
    }

    export interface Graphics
    {
        Image: typeof State & ImageClass & (new () => typeof State & ImageClass);
    }
}

declare var Graphics: Lib.Graphics;

그런 다음 다음과 같이 입력합니다.

var someEnum = Graphics.Image.STATE_ERROR;
var image = new Graphics.Image();
var anotherEnum = image.STATE_IDLE;

나는 것을 감사하지만 기존의 라이브러리, 뭔가 내 통제 불능 'Graphics.Image.State.STATE_ERROR'너무에 대한 선언을 작성하려고 한 것 나를 위해하지 작업 -이 'Graphics.Image.STATE_ERROR'이어야한다
Lewis Peel

@LewisPeel 아, 죄송합니다. 답변을 업데이트했습니다. 그게 가치를 제공할까요?
Alex

2

나는 해결책을 찾았을 수도 있다고 생각합니다 ... 유효한 TypeScript인지는 모르겠지만 작동하며 컴파일 오류가 발생하지 않습니다. 위 답변의 조합입니다.

declare module 'Lib' {

  module Graphics {

    module Image {
      enum State { }
      var STATE_IDLE: State;
      var STATE_LOADING: State;
      var STATE_READY: State;
      var STATE_ERROR: State;
    }

    class Image {
      constructor();
    }

  }

}

내가 알아 차리지 못한 잠재적 인 문제를 발견 할 수있는 사람이 있습니까?


아무것도 영향을주지 않고 열거 형 내부에서 값을 제거 할 수도 있습니다.
Lewis Peel

이제 두 가지 방법으로 액세스 할 수 있습니다. Image.State.STATE_IDLEImage.STATE_IDLE. 누군가가 당신의 정의를보고 그들이 무엇을 사용해야하는지 알아내는 것은 조금 어렵습니다.
David Sherret 2015

진실. 대답을 편집하고 열거 형 내부에서 값을 제거했습니다. 이것은 실제로 threejs가 정의 파일에있는 것과 같습니다.
Lewis Peel

1

무엇을 하려는지 잘 모르겠지만 enum가능한 상태 값 state을 나타내는을 원하고 이미지의 현재 상태를 나타내는 멤버를 원할 것으로 예상했을 것입니다 .

declare module 'Lib' {
    export module Graphics {

        enum State {
            STATE_IDLE,
            STATE_LOADING,
            STATE_READY,
            STATE_ERROR
        }

        export class Image {
            public state: State;

            constructor();
        }

    }
}

클래스 내에서 열거 형을 선언하는 대신 열거 형과 유사한 멤버가있는 클래스를 선언하려는 것처럼 들립니다. 즉 :

declare module 'Lib' {

    export module Graphics {

        export class Image {
            static STATE_IDLE: number;
            static STATE_LOADING: number;
            static STATE_READY: number;
            static STATE_ERROR: number;

            constructor();
        }
    }
}

답장 주셔서 감사합니다 Steve. 상태 값에 액세스하는 방법은 이와 같습니다. Lib.Graphics.Image.STATE_READY가 아닌 공용 재산-내 결정은 아니지만 그것이 라이브러리의 방식입니다. 클래스에서 정적 열거를 수행하는 방법이 있습니까?
Lewis Peel

이 경우 Image클래스 에 열거 형과 같은 멤버를 선언하고 싶을 것입니다 ( number열거 형이 내부에있는 것처럼 유형 이 될 것입니다 ).
Fenton 2015

내가 참조. 유휴, 로딩, 준비 또는 오류 만 허용해야하는 함수가 있지만, 이러한 기능 중 하나가 아니면 허용되지 않아야합니다. 내가 숫자로 선언하면 사람들이 "100"을 보낼 수 있고 유효할까요?
Lewis Peel

0

같은 이름으로 모듈과 클래스를 만들 수 있습니다. State두 번 말할 필요가 없도록 열거 형 이름을 바꾸는 것도 도움이 될 수 있습니다 .

declare module 'Lib' {
    export module Graphics {
        export class Image {
            constructor();
        }

        export module Image {
            export enum State {
                Idle,
                Loading,
                Ready,
                Error
            }
        }
    }
}

클래스 내에서 클래스만드는 경우 에도 동일하게 적용됩니다 .
David Sherret 2015-04-24

그건 좀 작동하지만 내가 대신 "Lib.Graphics.Image.STATE_IDLE"의 "Lib.Graphics.Image.State.STATE_IDLE"쓰기에 의미
루이스 필

2
@LewisPeel 당신이 찾고있는 것은 클래스의 열거 형이 아니라 클래스의 정적 숫자 속성입니다. Steve의 대답을 사용하되 각 속성에 값을 명시 적으로 지정하십시오. static STATE_IDLE: number = 0; static STATE_LOADING: number = 1;etc ...
David Sherret

그게 내 유일한 선택이라고 생각합니다. 내가 말했듯이 Image.STATE_LOADING 대신 100을 사용할 수 있고 컴파일러가 플래그를 표시하지 않기 때문에 부끄러운 일이지만 코드가 실행되면 오류가 발생합니다.
Lewis Peel

오,이게 정의 파일 인 걸 잊었 네요. 해당 멤버에 값을 할당 할 수는 없지만 해당하는 javascript 파일에서 지정해야합니다 (원래 속성이 아니라 멤버라고 말하려 함)
David Sherret 2015-04-24
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.