Javascript Conditional Inside TypeScript Interface

Viewed 16385

Is it possible to have a condition inside of an interface declaration in TypeScript. What I'm looking for is a way to say, based on the value of the first key, the second key can be these values.

Example (non functioning):

interface getSublistValue {

    /** The internal ID of the sublist. */
    sublistId: 'item' | 'partners';

    /** The internal ID of a sublist field. */
    if (this.sublistId === 'item') {
        fieldId: 'itemname' | 'quantity';
    }

    if (this.sublistId === 'partners') {
        fieldId: 'partnername' | 'location';
    }
}
4 Answers

If you would like to completely separate out your interfaces you could do something like this:

eg. sublist.model.ts

interface SublistItem {
    sublistId: 'item';
    fieldId: 'itemname' | 'quantity';
}

interface SublistPartners {
    sublistId: 'partners';
    fieldId: 'partnername' | 'location';
}

export type Sublist = SublistItem | SublistPartners;

Now you can use the Sublist type and it will correctly infer whether it is of type SublistPartners or SublistItem depending on the field values you provide.

You can try to solve this problem using conditional types:

interface SublistItem {
    sublistId: 'item';
    fieldId: 'itemname' | 'quantity';
}

interface SublistPartners {
    sublistId: 'partners';
    fieldId: 'partnername' | 'location';
}

type ConditionalSublist<bIsSublistItem=true> = bIsSublistItem extends true ? SublistItem : SublistPartners;

let sublistItem: ConditionalSublist<true> = {
    fieldId: "itemname",
    sublistId: "item"
};

let sublistPartner: ConditionalSublist<false> = {
    fieldId: "partnername",
    sublistId: "partners"
};

You may use my example. After providing required props, typescript will suggest other props.

interface _ButtonProps {
  variant: 'flat' | 'primary';
}

interface FlatButton extends _ButtonProps {
  variant: 'flat';
  textColor?: string;
}

interface PrimaryButton extends _ButtonProps {
  variant: 'primary';
  backgroundColor?: string;
}

export type ButtonProps = FlatButton | PrimaryButton;
Related