Typescript Interfaces - Two possible key names for one property

Viewed 48

I have this interface, I was curious if there is a possible way to specify potential names that the key value could be. But I still get reference errors saying "bottom" isn't apart of IStyles. I am fairly new to using typescript, and when searching through stackoverflow, none of the other answers regarding what I was looking for jumped out at my immediately as the answer so I apologize if this is already somewhere and I have overlooked it.

I am looking to achieve something like this for a Svelte project I am working on as these key-names are obviously css names, so its imperative that I use the actually naming.

interface IStyles
    {
        position?: string;
        [top | bottom] ?: string | number;
        margin?: string | number;
        padding?: string | number;
        background?: string | Colors;
    }
2 Answers

You cannot declare properties like that.

One thing that you can do is to group your common keys in an object and then use intersection types to create more complex types. Something similar to this:

const Common = {
  top: 0,
  bottom: 0,
};

type IStyles = {
  position?: string;
  margin?: string | number;
  padding?: string | number;
  background?: string | Colors;
} & {  
  [Prop in keyof typeof Common]: string | number;
}

let a: IStyles = {
}

If I understood your question right, you wanted that top and bottom properties are exclusive.

This is possible in TypeScript, but only with "type" and not with "interface", but most often both can be used very similar. So maybe this works for you:

type TopOrBottom = { top?: string | number; bottom?: undefined } | { top?: undefined; bottom?: string | number }

type IStyles = TopOrBottom & {
    position?: string;
    margin?: string | number;
    padding?: string | number;
    background?: string;
};

const validTop: IStyles = { top: 123 };
const validBottom: IStyles = { bottom: '12px' };
const invalid: IStyles = { bottom: '12px', top: 12 }; // TS error

See here

Related