Home > OS >  Union by multiple basic types
Union by multiple basic types

Time:03-23

export type CustomProps<T> = {
  value: string | number | boolean;
  entity: T;
};

I've created type , which have value prop, and it can take string, number, boolean , but when I try to use it , and assign to value for example one of those types value: string , it says me

Type 'string | number | boolean' is not assignable to type 'string'.

Code:

interface Props {
  entity: BankI;
  value: string;
}

const Value = ({ value, entity }: Props) => {
  const id = useMemo(() => generateUuid()   entity._id, [entity._id]);

  return (
    <div className={styles.root}>
      <p className={styles.body1} id={id}>
        {value}
      </p>
    </div>
  );
};
const object = {
        // Error occurs in this line on <Value /> component
        custom: (props: CustomProps<BankI>) => <Value {...props} />,
}

Error occurs, where I call Value component , Value component have props , which showed above , in proops I assign string type to value, my type CustomProps should take value as one of types (string, boolean, number)

CodePudding user response:

There are two different approaches you can take to get around this. One would be to add a type parameter to CustomProps which specifies the type of value:

export type CustomProps<T, V extends string | number | boolean> = {
  value: V;
  entity: T;
};

The other approach would be to add a discriminator field that indicates what the value type is, like so:

export interface CustomPropsBase<T> {
  entity: T;
}

export interface StringCustomProps<T> extends CustomPropsBase<T> {
  valueType: 'string';
  value: string;
}

export interface BooleanCustomProps<T> extends CustomPropsBase<T> {
  valueType: 'bool';
  value: boolean;
}

export interface NumberCustomProps<T> extends CustomPropsBase<T> {
  valueType: 'number';
  value: number;
}

export type CustomProps<T> = StringCustomProps<T> | BooleanCustomProps<T> | NumberCustomProps<T>;

With the second approach, TypeScript will automatically know when you check valueType what the type of value is, e.g.:

function myFunc(customProp: customProps<Foo>) {
  if (customProp.valueType === 'string') {
    // Typescript knows `value` is string
    let str: string = customProp.value;
  }
}

You would set the valueType when you create the CustomProps instance to match the type you are using, e.g.:

let x: StringCustomProps<Foo> = {
  entity: myFooObj,
  value: 'My string value',
  valueType: 'string'
}
  • Related