Describe property object in TypeScript interface

Alendorff picture Alendorff · Mar 17, 2017 · Viewed 29.6k times · Source

I want to describe some interface with nested objects. How can I do it without creation of Interfaces for nested objects?

interface ISome {
  strProp:string;
  complexProp:{
    someStrKeyWhichIsDynamic:{
      value:string;
      optValue?:string;
    }
  };
}

I also tried (UPD: it's okay actually)

interface ISome {
  strProp:string;
  complexProp:{
    [someStrKeyWhichIsDynamic:string]:{
      value:string;
      optValue?:string;
    }
  };
}

But I cant to assign an object like

let dynamicStrKey = 'myKey';
  {
   strProp:'str', 
   complexProp:{
     [dynamicStrKey]:{
       value:'something here',
       optValue: 'ok, that too',
    }
  };

to variable with ISome type without type assertion <ISome>. At least WebStorm highlights this assignment as an error.

How to properly describe nested objects?

Answer

Alendorff picture Alendorff · Mar 19, 2017

Finally, I think that my second variant was correct

interface ISome {
  strProp:string;
  complexProp:{
    [someStrKeyWhichIsDynamic:string]:{
      value:string;
      optValue?:string;
    }
  };
}

For dynamic key you can just write [dynamic:string] to specify that here will be some string property. Seems like I had webstorm error which wasn't related to the issue.

BTW, if you have some string based enum, you may want to use [key in MyEnum]: {...} instead of [key:string]. That solves error:

TS1337 an index signature parameter type can not be a union type.

And if you have a literal object, e.g. const obj = { prop1: 'blah', prop2: 'blahblah' }

You may want to use [key in keyof typeof obj]: {...} to describe that your dynamic key can be only 'prop1' or 'prop2' (or, more generic, value from Object.keys(obj) )