Enum inside class (TypeScript definition file)

后端 未结 7 1676
再見小時候
再見小時候 2021-01-31 01:20

I\'ve searched around but can\'t seem to find an answer for this, hopefully you can help. How can I add an enum to Image? This is what I would like ideally but I get an error.

相关标签:
7条回答
  • 2021-01-31 01:30

    I think the following is an improvement on KoenT's solution:

    export class Image
    {
        constructor ()
        {
            this.state = Image.State.Idle;
        }
    
        state: Image.State;
    }
    
    export namespace Image
    {
        export enum State
        {
            Idle,
            Loading,
            Ready,
            Error
        }
    }
    

    The advantage being that you can leverage named imports:

    import {Image} from './image';
    let img = new Image()
    img.state = Image.State.Error
    
    0 讨论(0)
  • 2021-01-31 01:34

    I also bumped into this problem recently. This is what I am currently using as a solution:

    // 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;
    

    Then in the place where I'm using the class and its enum:

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

    This seems to work fine (even though I don't consider it as the expected way to do this kind of thing).

    Hopefully there will be a way in TypeScript to do it this way:

    class Image
    {
        enum State
        {
            Idle,
            Loading,
            Ready,
            Error
        }
    
        constructor()
        {
            this.state = State.Idle;
        }
    
        state: State;
    }
    
    export = Image;
    
    0 讨论(0)
  • 2021-01-31 01:37

    Here's my solution.

    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);
        }
    }
    

    Usage:

    let program = new Program({ title: `some title` });
    
    program.status = Program.Status.New;
    

    or

    program.status = program.Status.New;
    

    Added benefit for Angular 2+ users: this can be used in templates

    <div *ngIf="program.status === program.Status.New">
      Only display if status of the program is New
    </div>
    
    0 讨论(0)
  • 2021-01-31 01:38

    You could create a module and class with the same name. It might also help to rename your enum so that you don't have to say State twice:

    declare module 'Lib' {
        export module Graphics {
            export class Image {
                constructor();
            }
    
            export module Image {
                export enum State {
                    Idle,
                    Loading,
                    Ready,
                    Error
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-31 01:40

    I think that this stuff with module augmentation is a very hacky and non-intuitive way* of doing things, so consider this:

    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;
    

    That is, just declare the enum in the scope of the class that you want to add it to without exporting it, then expose it through a member of the class.

    * Which in regards of structuring and organization of code is BAD, even if it technically works.

    Update

    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;
    

    Then you get typing like:

    var someEnum = Graphics.Image.STATE_ERROR;
    var image = new Graphics.Image();
    var anotherEnum = image.STATE_IDLE;
    
    0 讨论(0)
  • 2021-01-31 01:46

    I'm not sure what you intend to do, but I would have expected that you would want an enum to represent the possible state values, and then a state member on the image to indicate the current state of the image.

    declare module 'Lib' {
        export module Graphics {
    
            enum State {
                STATE_IDLE,
                STATE_LOADING,
                STATE_READY,
                STATE_ERROR
            }
    
            export class Image {
                public state: State;
    
                constructor();
            }
    
        }
    }
    

    It sounds like you want to declare a class that has enum-like members, rather than declare an enum within a class. i.e:

    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();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题