30

How do I place a constant in an Interface in typescript. Like in java it is:

interface OlympicMedal {
  static final String GOLD = "Gold";
  static final String SILVER = "Silver";
  static final String BRONZE = "Bronze";
}
roshan
  • 2,410
  • 2
  • 25
  • 37

6 Answers6

30

You cannot declare values in an interface.

You can declare values in a module:

module OlympicMedal {
    export var GOLD = "Gold";
    export var SILVER = "Silver";
}

In an upcoming release of TypeScript, you will be able to use const:

module OlympicMedal {
    export const GOLD = "Gold";
    export const SILVER = "Silver";
}

OlympicMedal.GOLD = 'Bronze'; // Error
Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235
10

Just use the value in the interface in place of the type, see below

export interface TypeX {
    "pk": "fixed"
}

let x1 : TypeX = {
    "pk":"fixed" // this is ok
}

let x2 : TypeX = {
    "pk":"something else" // error TS2322: Type '"something else"' is not assignable to type '"fixed"'.
}
Bing Ren
  • 1,589
  • 17
  • 26
4

Since nobody gave the actual answer of how to do it with an interface (to be used in interface/class merging for example).

interface Medals {
  GOLD: 'gold';
  SILVER: 'silver';
  BRONZE: 'bronze';
}

This will make

const a: Medals = { ... }
// type of a.GOLD is the literal 'gold'

Although you should consider using an enum or const medals = { ...definition } as const or even a class.

Appendix: Objects, Arrays and Classes

Const arrays and const objects can be done like this.

const constArray = ['array', 'of', 'emperor', 'Constantine'] as const;
const constObj = { gold: 'GOLD', silver: 'SILVER', bronze: 'BRONZE' } as const;

interface Constants {
  constArray: typeof constArray;
  constObj: typeof constObj;
}

const obj: Constants = {} as any;
const str = obj.constArray[3]; // str has type 'Constantine'
const gold = obj.constObj.gold; // gold has type 'gold'

For a class-based approach

class Medals {
  static readonly GOLD = 'gold';
  static readonly SILVER = 'silver';
  static readonly BRONZE = 'bronze';
}

// Medals.GOLD has literal type 'gold'
Caveman
  • 2,527
  • 1
  • 17
  • 18
3

There is a workaround for having constants in a interface: define both the module and the interface with the same name.

In the following, the interface declaration will merge with the module, so that OlympicMedal becomes a value, namespace, and type. This might be what you want.

module OlympicMedal {
    export const GOLD = "Gold";
    export const SILVER = "Silver";
}

interface OlympicMedal /* extends What_you_need */ {
    myMethod(input: any): any;
}

This works with Typescript 2.x

Gianpiero
  • 3,349
  • 1
  • 29
  • 42
3

A recommended way to establish constants in an interface, as shown here and is similar to another answer here, is to do:

export class Constants {
  public static readonly API_ENDPOINT = 'http://127.0.0.1:6666/api/';
  public static readonly COLORS = {
    GOLD: 'Gold',
    SILVER: 'Silver',
    BRONZE: 'Bronze'
  };
}

This is the preferred way to define constants without being hacky, or disabling settings in the TSLinter (because module and namespace will throw many warnings via the linter).

NonCreature0714
  • 5,744
  • 10
  • 30
  • 52
0

This seems to work:

class Foo {
  static readonly FOO="bar"
}

export function foo(): string {
  return Foo.FOO
}

You can have private constants as well like this. It seems interfaces can't have static members though.

Jilles van Gurp
  • 7,927
  • 4
  • 38
  • 46