Alwaysblue
Alwaysblue

Reputation: 11900

Conditional boolean type in typescript with interface

How would I write conditional boolean type for this?

i.e

export interface Props {
  editable: boolean;
  position: { editable: true } ? Sheets.Matrix : never;
  value: string;
  classNames?: string;
  textType?: "bold" | "editing" | "normal";
  onChange?: (val: Sheets.SaveData) => void;
}

I use props like this

const SheetsCell: React.FC<MainProps> = ({
  editable,
  value,
  textType = "normal",
  classNames = "",
  position,
  ...

Here if something is editable, I want the type of position to be Sheets.Matrix else, position isn't required.

Upvotes: 1

Views: 465

Answers (2)

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37604

You could use type aliases instead of an interface e.g.

type Props = { 
  editable: true;
  position: Sheets.Matrix;
} | { 
  editable: false;
};

const testFalse: Props = { // position not required
  editable: false
}
    
const testTrue: Props = { // position mandatory
  editable: true,
  position: MatrixEnum
}

Upvotes: 1

Tushar Shahi
Tushar Shahi

Reputation: 20626

One way to do it is using an interface and the intersection operator(&).

You can use an intersection type, which combines multiple types into one.

interface Props {
  value: string;
  classNames?: string;
  textType?: "bold" | "editing" | "normal";
  onChange?: (val: number) => void;
}

type MainProps = Props & {
  editable: true;
  position: number; 
} | Props & {
  editable: false;
  position?: number; 
}; 

The above type MainProps forces editable to be true in one case and false in another. If editable is true, then position property exists and if it is false, position property exists but it is not required.

unions is used above, to generate a type which can be one of the two values. MainProps can be one of the two types (both being intersection with Props type).

Here is the playground link

Upvotes: 1

Related Questions