Home > database >  Dynamically change type based on variable
Dynamically change type based on variable

Time:01-30

So I really don't know if this is possible but I wanted to ask anyway. So I have a class named Row

export class Row {
    buttons: MenuOption[] | ButtonOption[];
    rowType: RowTypes;
    constructor(buttons: MenuOption[] | ButtonOption[], rowType: RowTypes) {
        this.buttons = buttons;
        this.rowType = rowType;
    }

}

And it has a property called rowType which is basically an enum

export enum RowTypes {
    SelectMenu = 0,
    ButtonMenu = 1
}

It also has a property called buttons and It can be either a MenuOption array, or a ButtonOption array. Now here's the problem. Can I tell typescript to change the type of the property buttons based on the rowType value? So for example if the rowType value is 1 then the buttons type is MenuOption.

CodePudding user response:

You can use constructor overloads so that you can ensure a 1:1 correspondence between RowTypes and the type of the buttons argument:

export class Row {
    buttons: MenuOption[] | ButtonOption[];
    rowType: RowTypes;
    
    constructor(buttons: MenuOption[], rowType: RowTypes.SelectMenu)
    constructor(buttons: ButtonOption[], rowType: RowTypes.ButtonMenu)
    constructor(buttons: MenuOption[] | ButtonOption[], rowType: RowTypes) {
        this.buttons = buttons;
        this.rowType = rowType;
    }
}

See proof-of-concept on TypeScript Playground.

CodePudding user response:

You can type constructor arguments to make code a bit cleaner, e.g.

type RowCtor = {
  buttons: MenuOption[];
  rowType: RowTypes.SelectMenu;
} | {
  buttons: ButtonOption[];
  rowType: RowTypes.ButtonMenu;
}

export class Row {
    buttons: MenuOption[] | ButtonOption[];
    rowType: RowTypes;
    constructor(args: RowCtor) {
        this.buttons = args.buttons;
        this.rowType = args.rowType
    }
}
  •  Tags:  
  • Related