Oguntoye
Oguntoye

Reputation: 685

Is it possible to conditionally require a property in a Typescript interface

Say I have the following interface:

interface updateOptions {
  updateAll: boolean;
  fields: string[];
}

Is there a way to make updateAll required when Fields is not provided and vice versa, or is this something that must be done conditionally in the implementation?

Upvotes: 4

Views: 1388

Answers (1)

Maybe Julius
Maybe Julius

Reputation: 1234

Use tagged union type:

type UpdateOptions =
  | {updateAll: true}
  | {updateAll: false, fields: string[]}

This way you can only initialize {updateAll: true} or {updateAll: false, fields: ['someField', /*...*/]}

Technically, the union doesn't need to have a tag (the boolean updateAll), but then you need to define type guard to test which type is being used in a particular branch (I assume somewhere in your code you will do if (options.updateAll) {/* ... */}):

type UpdateAllOptions = {updateAll: true}
type UpdateSomeOptions = {fields: string[]}
type UpdateOptions = UpdateAllOptions | UpdateSomeOptions

// See https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
const isAllOptions = (options: UpdateOptions): options is UpdateAllOptions =>
  (options as any).updateAll === true

Upvotes: 6

Related Questions