Enforce static member in class using enum

1.2k Views Asked by At

I have this:

declare enum Foods {
  CHERRY = 'CHERRY',
  LETTUCE = 'LETTUCE',
  JERKY = 'JERKY'
}

declare abstract class ForceFoods {
  static food : Foods
}

export class MyFoods implements ForceFoods {

  static food = Foods.CHERRY;

}

But here is the error that I don't know how to solve:

enter image description here

Does anyone know how to fix that the ambient initializer error?

Here is the error:

"Initializers are not allowed in ambient contexts"

I also get this error sometimes:

"Ambient declaration should have no initializer"
3

There are 3 best solutions below

0
On

The reason for the error was because all the code was in a declaration file (.d.ts). To fix the error, put the implementing class in a .ts file:

// index.d.ts

export enum SCEPluginTypes {

  LANGUAGE = 'SCE_LANGUAGE'

}


declare enum Foods {
  CHERRY = 'CHERRY',
  LETTUCE = 'LETTUCE',
  JERKY = 'JERKY'
}


declare abstract class ForceFoods {
  static food : Foods
}

// index.ts

import {Foods, ForceFoods} from "./index";

export class MyFoods implements ForceFoods {

  static food = Foods.CHERRY;

}
2
On

As you mentioned in the comments, this code is in a declaration file—.d.ts file—and that makes sense based on the error you're receiving. Declaration files can only have ambient definitions (ex. declare class MyFoods {}) in them because they're meant to describe the type information of objects rather than be the actual implementation of them.

By the way, there's currently no way to enforce static properties like what you're attempting to do there. There's several alternatives. For example, you may want to use a singleton pattern instead:

// in a .ts file
export enum Foods {
  CHERRY = 'CHERRY',
  LETTUCE = 'LETTUCE',
  JERKY = 'JERKY'
}

export interface ForceFoods {
  food: Foods;
}

export class MyFoods implements ForceFoods {
  private static _instance: MyFoods | undefined;

  food = Foods.CHERRY;

  private constructor() {
  }

  static get instance() {
    return this._instance || (this._instance = new MyFoods());
  }
}

// then use...
MyFoods.instance.food;
0
On
declare enum Foods {
  CHERRY = 'CHERRY',
  LETTUCE = 'LETTUCE',
  JERKY = 'JERKY'
}

// class interface
interface ForceFoodsClass {
    food : Foods
    new (): ForceFoods;
}

// instance interface
interface ForceFoods {
    // just to show you will need to add a name property
    name: string;
}


export const MyFoods:ForceFoodsClass = class implements ForceFoods {

  static food = Foods.CHERRY;
  name = "Cherry pick"
}

Playground