roshan
roshan

Reputation: 2510

Typescript: constants in an interface

How do I place a constant in an interface in TypeScript? In Java, it would be this:

interface OlympicMedal {
    static final String GOLD = "Gold";
    static final String SILVER = "Silver";
    static final String BRONZE = "Bronze";
}

Upvotes: 34

Views: 63743

Answers (6)

Caveman
Caveman

Reputation: 2963

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'

Upvotes: 5

NonCreature0714
NonCreature0714

Reputation: 6024

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).

Upvotes: 3

Bing Ren
Bing Ren

Reputation: 1785

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"'.
}

Upvotes: 11

Jilles van Gurp
Jilles van Gurp

Reputation: 8334

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.

Upvotes: 0

Gianpiero
Gianpiero

Reputation: 3567

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

Upvotes: 3

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 221402

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

Upvotes: 30

Related Questions