Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why typescript does not ensure type safety in a generic higher order component that adds additional properties in React?

I'm trying to create a generic higher order component and type safety is not checked. When doing the same but in a not generic way, the type safety is checked as expected.

interface IBaseProps {
  baseValue?: string;
}

const Base = (props: IBaseProps) => {
  return <span>{"value: " + props.baseValue}</span>;
};

interface IExtraProps {
  extraValue?: string;
}

const foo = <T extends IBaseProps>(
  Element: React.ComponentType<T>
): React.ComponentType<T & IExtraProps> => (props: T & IExtraProps) => {
  const baseValue = `${props.baseValue} extra value: ${props.extraValue}`;
  return <Element {...props} baseValue={baseValue} />; // example
};

const bar = <T extends IBaseProps>(
  Element: React.ComponentType<T>
): React.ComponentType<T & IExtraProps> => (props: T & IExtraProps) => {
  return <Element {...props} baseValue={42} />; // NO error, why?
};

const baz = <T extends IBaseProps>(
  Element: React.ComponentType<T>
): React.ComponentType<T & IExtraProps> => (props: T & IExtraProps) => {
  return <Element {...props} unknownProp={42} />; // NO error, why?
};

const bag = (props:IBaseProps) => {
  const baseValue = props.baseValue + ' augmented'
  return <Base {...props} baseValue={42} />; // ok, error is detected
}

Demo can be found here

How to make Typescript check types correctly?

like image 273
Daniel Avatar asked Nov 22 '25 06:11

Daniel


1 Answers

Everything is right with typescript. The Base component is declared above and has a type to IBaseProps.That is why it shows an error.

The bar has

React.ComponentType<T & IExtraProps> 

It basically means that T can be any type. So it is not showing any errors.

The others also have T & IExtraProps types. Check it by hovering to any of them ( bar, baz , foo , bag ). Everything is working correctly in this code.

like image 171
David Galoyan Avatar answered Nov 24 '25 22:11

David Galoyan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!