1

I'm trying to create some UI utility components with React Typescript. These utilities are meant to provide some default styling to HTML elements.

FullScreen is just a <div> whose height is 100vh and whose width is 100vw.

So I figured FullSreenProps should extend HTMLDivElement. But when I spread props.style into the style property, I get a type error:

Type '{ width: string; height: string; accentColor: string; alignContent: string; alignItems: string; alignSelf: string; alignmentBaseline: string; all: string; animation: string; animationDelay: string; ... 443 more ...; [Symbol.iterator](): IterableIterator<...>; }' is not assignable to type 'CSSProperties'.
  Types of property 'appearance' are incompatible.
    Type 'string' is not assignable to type 'Appearance'.ts(2322)

Here's the FullScreen component:

import React, { useState, useEffect, useMemo } from 'react';


interface FullScreenProps extends HTMLDivElement{}

const FullScreen = (props: FullScreenProps): JSX.Element => {
    return (
      <div
      {...props}
      style={
          {
            ...props.style,
            width: "100vw", 
            height: "100vh",
          }
      }
      >
      </div>
    );
}
export default FullScreen

What's the correct way to pass props.style while also specificying height: 100vh and width: 100vw in the style prop?

1 Answer 1

1

HTMLDivElement is the native browser interface for the div element. However, to use it as prop-type for react's div, you have to wrap it in React.HTMLProps<...> interface.

Coming to the Omit part, you need to omit ref because you cannot read ref from props. You need to use the React.forwardRef HOC and get it as a second argument to your Functional Component.

And, as is a special prop which we can use to replace the component. For eg. <Typography as="h1">Hi there</Typography> or <Typography as="h4">Hi there</Typography>, etc and in the Typography component, you can do the following:

const Typography = (props) => {
  const {as: Component, children, ...other} = props;
  return (
    <Component {...other}>{children}</Component>
  );
}

Now, if you want to use it in your component, then you can (don't omit it). But, be sure to remove it from props before spreading them into the div element as it is not accepted by div.

You can try the following:

import React from 'react';


interface FullScreenProps extends Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'ref'> {}

const FullScreen = (props: FullScreenProps): JSX.Element => {
    return (
      <div
      {...props}
      style={
          {
            ...(props.style || {}),
            width: "100vw", 
            height: "100vh",
          }
      }
      >
      </div>
    );
}
export default FullScreen
Sign up to request clarification or add additional context in comments.

2 Comments

This works! Any chance you could elaborate on your answer? Seems like we need to remove the as and ref props, but why?
Added explanation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.