Yevgeniy Brikman
Yevgeniy Brikman

Reputation: 9361

In a TypeScript interface, is it possible to limit the keys in one property to the values of another property?

Consider the following TypeScript interface:

interface Foo {
  list: string[];
  obj: { [index: string]: string; };
}

Is there a way to specify the types so that that the keys in obj must be one of the values in list?

For example, the following would be valid:

class Bar implements Foo {
  list = ["key1", "key2"]
  obj = {"key1": "value1"}
}

However, the following would be a compile error:

class Bar implements Foo {
  list = ["key1", "key2"]
  // COMPILE ERROR
  // "some-other-key" is not in list
  obj = {"some-other-key": "value1"}
}

I've tried to limit the type of obj using keyof and Lookup Types, but have not been successful.

Upvotes: 1

Views: 846

Answers (1)

Remo H. Jansen
Remo H. Jansen

Reputation: 24979

I removed list: string[] because I assume that you don't really need it at runtime. This solution works at compile time:

interface Foo<T extends string[]> {
  obj: { [index in T[number]]?: string; };
}

class Bar1 implements Foo<["key1", "key2"]> {
  obj = {"key1": "value1"} // OK
}

class Bar2 implements Foo<["key1", "key2"]> {
  obj = {"some-other-key": "value1"} // Error :)
}

Upvotes: 5

Related Questions