test
test

Reputation: 18200

TypeScript - Interface. Define a property with either empty object or this object

Take for example this TypeScript code:

interface IBook {
    metadata: {} | {
        title: string;
        author: string
    };
}

const bookOne: IBook = {
    metadata: {}
};

const bookTwo: IBook = {
    metadata: {
        TEST: 'Red Book',
    }
};


As you can see, metadata can only be an object. But, what I'm trying to figure out, how do I make it either empty object ({}) or if it needs to have properties within that object to make it only title and author.

I think I know why it's wrong but I can't seem to find the either. Help?

Upvotes: 2

Views: 348

Answers (2)

Matei Radu
Matei Radu

Reputation: 2078

If it is OK to potentially have subsets of metadata then Hitmands' answer works just fine because it would allow you to have only author, only title or both.

Otherwise, if you are looking for an "all or nothing" scenario, I would go with making metadata optional:

interface IBook {
    metadata?: {
        title: string;
        author: string
    };
}

TypeScript Playground example

This way, you either have a complete metadata object or nothing.

As an alternative, you could make metadata possibly undefined:

interface IBook {
    metadata: undefined | {
        title: string;
        author: string
    };
}

However, this makes the assignment of metadata mandatory even when there is no data:

// Error. Property `metadata` is missing but required in type `IBook`.
const bookOne: IBook = {};

// Valid.
const bookTwo: IBook = {
    metadata: undefined
};

Upvotes: 3

Hitmands
Hitmands

Reputation: 14159

It looks like neither title, nor author are required properties... so better to mark them as optional imho.

interface IBook {
  metadata: {
    title?: string;
    author?: string;
  };
}

Upvotes: 1

Related Questions