类中的枚举(TypeScript 定义文件)

我四处寻找,但似乎找不到这个问题的答案,希望你能帮忙。

我怎样才能添加一个枚举到 Image? 这是我想理想的,但我得到了一个错误。

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,这是不正确的。它需要成为 Image的一部分。

108682 次浏览

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

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

I think I may have found a solution...whether it's valid TypeScript I don't know but it works and doesn't cause any compile errors. It's a combination of the above answers.

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


}


}

Can anyone spot any potential issues with this that I haven't noticed?

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;

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;

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

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>