rebass icon indicating copy to clipboard operation
rebass copied to clipboard

Typescript Ref

Open phmatray opened this issue 5 years ago • 1 comments

Hello,

I'm having some kind of weird mistake with the refs. I've been trying to get forwardRef to work for several days... maybe I missed something, maybe there's a typing issue with @theme-ui/components.

Type 'Ref<unknown>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'RefObject<unknown>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
    Type 'RefObject<unknown>' is not assignable to type 'RefObject<HTMLDivElement>'.
      Type 'unknown' is not assignable to type 'HTMLDivElement'.

I reproduced the error in that sandbox. https://codesandbox.io/s/interesting-kilby-r970e

Thanks

phmatray avatar Feb 15 '20 22:02 phmatray

After a lot of unsuccessful research and trials. I finally found the key to the problem. There is a type conflict between the 'color' property of styled-system and the 'HTMLAttributes' property.

Here is a functional but imperfect example thanks to an ugly hack.

import React, { FC, forwardRef } from 'react';
import classNames from 'classnames';
import { Box as $Box, BoxProps } from 'reflexbox';

export interface TitleProps extends BoxProps {
  isType?: 'title' | 'subtitle';
  isSize?: '1' | '2' | '3' | '4' | '5' | '6';
  isSpaced?: boolean;
}

export const Title = forwardRef<HTMLDivElement, TitleProps>(
  ({ isType = 'title', isSize, isSpaced, ...rest }, ref) => (
    <$Box
      as="div"
      color={rest.color as any} /* HACK */
      ref={ref}
      {...rest}
      className={classNames({
        [`${isType}`]: isType,
        [`is-${isSize}`]: isSize,
        'is-spaced': isSpaced,
      })}
    />
  )
);

https://stackoverflow.com/questions/53711454/styled-system-props-typing-with-typescript

phmatray avatar Feb 16 '20 16:02 phmatray