Bill
Bill

Reputation: 19308

Typescript extends object and exclude Date type

Is there a way to exclude Date type from object type. I have the following type for error within a form. However i am running into a problem where Date type is part of object.

export type FieldErrors<FormValues> = {
  [Key in keyof FormValues]?: FormValues[Key] extends any[]
    ? FormValues[Key][number] extends object
      ? FieldErrors<FormValues[Key][number]>[]
      : FieldError
    : FormValues[Key] extends object // this is the issue bit when extend object
    ? FieldErrors<FormValues[Key]>
    : FieldError
};


type FormData = {
  stringField: string;
  numberField: string;
  dateField: Date;
};

{errors.dateField && errors.dateField.message} // This result in error because Date type is object

Upvotes: 3

Views: 714

Answers (1)

ford04
ford04

Reputation: 74670

If you are asking for a negated type like FormValues[Key] extends object & not Date - they are not out yet.

Instead you can add a conditional step that checks for Date. Date is a subtype/more specific type than object, so this step should happen before the FormValues[Key] extends object check.

A good rule is to go from the most specific to the most general case. Here is an example:

interface FieldError { message: string }

export type FieldErrors<FormValues> = {
    [Key in keyof FormValues]?: FormValues[Key] extends any[]
    ? FormValues[Key][number] extends object
    ? FieldErrors<FormValues[Key][number]>[]
    : FieldError
    : FormValues[Key] extends Date // add conditional check for Date
    ? FieldError
    : FormValues[Key] extends object // ... before object check
    ? FieldErrors<FormValues[Key]>
    : FieldError
};

/*
type MyFormErrors = {
  stringField?: FieldError | undefined;
  numberField?: FieldError | undefined;
  dateField?: FieldError | undefined;
}
*/
type MyFormErrors = FieldErrors<FormData>

declare const errors: MyFormErrors
errors.dateField && errors.dateField.message // FieldError.message: string

Playground

Upvotes: 2

Related Questions