Record with optional keys with Typescript

Record with optional keys with Typescript

The Record type in Typescript is very useful. With it you can define an abstract object in more detail. This is very helpful when building a base interface for extending. With it you can do things like this:

export interface CommandWithFiles {
  body: object;
  files: Record<string, File>;
}

export interface CreateNewsEntryCommand extends CommandWithFiles {
  body: {
    date: Moment;
    title: string;
    content: string;
  },
  files: {
    attachment: DropzoneFile;
  }
}

But what to do if we want to have attachment in files optional? Then we wound need to build a custom type like the following:

type PartialRecord<K extends keyof any, T> = {
  [P in K]?: T;
};

export interface CommandWithFiles {
  body: object;
  files: PartialRecord<string, File>;
}

export interface CreateNewsEntryCommand extends CommandWithFiles {
  body: {
    date: Moment;
    title: string;
    content: string;
  },
  files: {
    attachment?: DropzoneFile;
  }
}

Or with another type supplied by Typescript called Partial:

export interface CommandWithFiles {
  body: object;
  files: Partial<Record<string, File>>;
}

export interface CreateNewsEntryCommand extends CommandWithFiles {
  body: {
    date: Moment;
    title: string;
    content: string;
  },
  files: {
    attachment?: DropzoneFile;
  }
}