2

I've got a question regarding a more dynamic kind of interface where dynamic and static properties can be used together - even if they are of different types. Is this possible? If yes, does it make any sense at all?

Let's say I want something like this.

type MyCustomType = {
    foo: string;
};

export interface MyInterface {
    [key: string]: MyCustomType;
    bar: string;
};

I want to make sure that a certain prop (that I do not know the name of in advance) points to a value of type MyCustomType. The rest of the properties in MyInterface I do know the names of and they point to other types.

The above code results in the following error:

Property 'bar' of type 'string' is not assignable to string index type MyCustomType.

I could get around that by using either intersection (as the below example) or any however.. that will also affect my dynamic prop and ruin guarantees of it's type.

export interface MyInterface {
    [key: string]: MyCustomType | string;
    bar: string;
};

Any suggestions are much appreciated :)

Ayman Arif
  • 1,456
  • 3
  • 16
  • 40
faerin
  • 1,915
  • 17
  • 31

1 Answers1

5

This can be done in the following way, using an intersection:

type MyCustomType = {
    foo: string;
};

type MyInterface = {
    [key: string]: MyCustomType;
} & { bar: string };

In order for intersections to work MyInterface has to be a type.

Ali Nasserzadeh
  • 1,365
  • 7
  • 15
  • How does this not answer the question @JaredSmith? This very much answers the question, I think you did not understand the question seeing your comment on the original post ;) – Ali Nasserzadeh Mar 31 '20 at 15:52
  • @AliNasserzadeh Awesome! Thank you :) Not that it matters, but could you clarify; does `MyInterface` has to be a `type` instead of an `interface` as in your example to work? If you clarify that in your post, I will not only mark it as the correct answer but also upvote it :) – faerin Mar 31 '20 at 17:01
  • @entiendoNull no problem :) yes it has to be a type for intersections to work – Ali Nasserzadeh Mar 31 '20 at 17:19