Home > OS >  Modeling an interface based on a different interface in TypeScript
Modeling an interface based on a different interface in TypeScript

Time:10-16

Suppose I have some interfaces in TypeScript:

export interface IStateA {
  id: number;
}

export interface IStateB {
  text: string;
  moreText: string;
}

Is there a way to generate the following interfaces without having to manually do so?

export interface IStateASetters {
  setId: (number) => void;
}

export interface IStateBSetters {
  setText: (string) => void;
  setMoreText: (string) => void;
}

Note the following:

  • the new interface name is the same as the old one, except with Setters appended
  • the new interface has methods that take in the type of the corresponding property of the old interface
  • the new interface method names are the same as the old property names, except with set prepended and the first letter of the old name capitalized.

Totally understandable if this isn't possible, partial answers are very welcome!

CodePudding user response:

If you combine a mapped type with string literals and key renaming, you can do this.

With something like:

type WithSetters<T> = {
     [K in keyof T & string as `set${Capitalize<K>}`]:
          (newValue: T[K]) => void
}

The one tricky part here is the & string. That's necessary because because a type may have non string keys (numbers, or symbols). But this transformation only makes sense for string keys. So by intersecting the keys with string you can be sure to only map the string keys.

Playground

  • Related