19

I have a constant:

const name = 'some/property';

I'd like to define an interface that uses name as a key for a property in a similar way to using it in an object declaration like so:

{[name]: 'Bob'}

I tried the following, but it seems that this is doing something else:

interface MyInterface {
  [name]: string;
}

is dynamically defining property names supported in typescript?

2 Answers 2

22

You have to specify the type of name. There's no way to use it in an object declaration but you can use the [ ] to set and access the property value.

interface MyInterface {
  [name: string]: string;
}
const n = 'qweq';

let x: MyInterface = {
  'a': 'b'
}

x[n] = 'a';

And access it this way.

x[n]

Check it out in the playground here.

Sign up to request clarification or add additional context in comments.

4 Comments

This doesn't work (or maybe my question is unclear). In your example, x.coolname is undefined.
You are right that was creating a property with the name n on the X object. I have updated my answer. :)
Thanks, but that is bypassing the typechecking completely, doing this will not enforce object of type MyInterface to have a qweg property
that's not very dynamic though. From what I know you can't define a type that allows an object to have any string as a key while at the same time enforcing a specific key name. The first includes the 2nd one.
10

This can be done with Mapped Types introduced in TypeScript 2.1:

const name = 'some/property';
type MyInterface = {
    [prop in typeof name]: string;
};

This forces all object of type MyInterface to have a property named 'some/property'.


I guess this answer is too late for you, but hopefully it can help others. I found this question early on in my own searches for a solution to a similar problem.

1 Comment

This helped! I had a related problem where I wanted a specific (dynamically-given) property inside of a type to have another given type, and ended up with type PropertyType<K extends string | number, T> = { [P in K]: T; }; const lala: PropertyType<'test', number> = { test: 1, };

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.