1

I have an object containing property names in the form:

const INPUT_NAMES = {
    FIRST_NAME: 'first-name',
    LAST_NAME: 'last-name'
};

I want to generate an interface based on those property name values:

interface IPropertyFormat {
    [INPUT_NAMES.FIRST_NAME]: string;
    [INPUT_NAMES.LAST_NAME]: string;
}

That doesn't work because I am not using a literal type, nor a symbol and I get this: A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.

Using a simple constant like:

const KEY = "FIRST_NAME";

interface IPropertyFormat {
    [KEY]: string;
}

works but is not an elegant solution in my case and would like to avoid it if possible. I've checked out this other kinda related topic but it doesn't provide a solution for my problem.

Anyone has any idea how to work around this problem?

EDIT:

Also, found a "some-what" solution at this post once again using const assertions.

zhulien
  • 5,145
  • 3
  • 22
  • 36
  • Does this answer your question? [TypeScript: Reverse map key-value type to value-key](https://stackoverflow.com/questions/60768302/typescript-reverse-map-key-value-type-to-value-key) – Nishant Feb 11 '21 at 18:28
  • @Nishant I am not even sure how this is connected to my question in any way. – zhulien Feb 11 '21 at 18:34
  • 1
    @zhulien maybe I have misunderstood, but does this solve your issue? https://tsplay.dev/rw2DYm it is the same thing in the duplicate question – Nishant Feb 11 '21 at 18:37
  • @Nishant Yes, this is more like it. Thank you. Like I noted, the `const assertion` is of great aid and I wasn't aware of the feature. – zhulien Feb 11 '21 at 18:53

1 Answers1

1

To have the correct litteral types in INPUT_NAMES you should use as const

Link to playground

const INPUT_NAMES = {
    FIRST_NAME: 'first-name' as const,
    LAST_NAME: 'last-name' as const
};

type Result =  {
    [k in typeof INPUT_NAMES[keyof typeof INPUT_NAMES]]: string
}

type Expected = {
    'first-name': string,
    'last-name': string
}

declare const x: Expected
declare const y: Result
// In case Result and Expected are different types, there will be an error
const a: Expected = y
const b: Result = x

If having an interface is very important:

interface myInterface extends Result {}
Ilario Pierbattista
  • 3,175
  • 2
  • 31
  • 41
  • Thank you for the extended solution including an interface. As I'm having different types for the properties I would still have to build the interface manually specifying each type separately but now I have the means to do it more DRY-ish. – zhulien Feb 11 '21 at 18:48