简体   繁体   中英

Javascript Conditional Inside TypeScript Interface

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';
    }
}

No there's not. The best thing to do is to create separate interfaces that describe the two different types of data.

For example:

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

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

function getData(): SublistItem | SublistPartners {
    return (Math.random() < 0.5)
        ? { sublistId: 'item', fieldId: 'itemname' }
        : { sublistId: 'partners', fieldId: 'partnername' };
}

const someValue = getData();

if (someValue.sublistId === "item") {
    // SublistItem in here
}
else {
    // SublistPartners in here
}

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM