question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Type [...] is missing the following properties from type Pick<ButtonHTMLAttributes,[...]: css, sx TS2739

See original GitHub issue

Describe the bug When consuming this component:

type Props = Omit<ButtonHTMLAttributes<HTMLButtonElement>, "className">;

const Button = React.forwardRef<HTMLButtonElement, Props>((props) => {
  return <button {...props} />
});

resulting in type (as reported by VS Code on hover & by inspecting the compiled d.ts):

const Button: React.ForwardRefExoticComponent<
  Pick<
    ButtonHTMLAttributes<HTMLButtonElement>,
    | "autoFocus"
    | "disabled"
    | "form"
    | "formAction"
    | "formEncType"
    | "formMethod"
    | ... 259 more ...
    | "sx"
  > &
    React.RefAttributes<...>
>;

from another Theme UI-agnostic project it encounters the following type error:

Type ‘{ children: string; }’ is missing the following properties from type ‘Pick<ButtonHTMLAttributes<HTMLButtonElement>, “autoFocus” | “disabled” | “form” | “formAction” | “formEncType” | “formMethod” | “formNoValidate” | … 258 more … | “sx”>’: css, sx TS2739

To Reproduce

  1. Clone https://github.com/yuriybelike/repro__theme-ui__css_sx_props
  2. On components-library, run npm i
  3. On consumer, run npm i
  4. On consumer – in order to see the TypeScript error – either:
    • open “src/App.tsx” on VS Code
    • run npm run start

Expected behavior

Consumer isn’t affected by Theme UI related types on primitive JSX elements like <button>

Additional context

  • I was unable to reproduce the issue when removing Omit<> or forwardRef()
  • I understand this is partially TypeScript’s issue, as it converts Omit<> into Pick<>
  • I’ve used tsdx for the library scaffolding, but I don’t think it is related, as my original project is using create-react-library
  • On my original project the issue was still reproducible on TypeScript v3.8.3

Workaround

You can just omit both props like

type Props = Omit<ButtonHTMLAttributes<HTMLButtonElement>, "className" | "css" | "sx">;

but I find it far from ideal having to account for Theme UI specific props on such a primitive type as it is ButtonHTMLAttributes

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
jxnblkcommented, Aug 3, 2020

@hasparus the more docs, the better, in my opinion. Feel free to add stuff as you go, even if it’s WIP or something we don’t link to

2reactions
hasparuscommented, Jul 26, 2020

but I find it far from ideal having to account for Theme UI specific props on such a primitive type as it is ButtonHTMLAttributes

I would be nice if TypeScript recognized sx and css prop only if jsx imported from Theme UI is set in the pragma comment for current file.

Unfortunately, JSX support in TypeScript isn’t perfect. It doesn’t work like this, and both Theme UI and Emotion inject its pragma supported prop into all React components.

Problem

I reproduced the problem.

  1. Our Omit is compiled to Pick. (Why? 😮)
  2. Because theme-ui is not a dependency of consumer, we don’t have sx prop (from Theme UI) nor css prop (from Emotion) types in it.
  3. So Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'sx'> is unknown. sx was optional, but we don’t know it in consumer.

I have two workarounds for you.

Workaround 1

Add theme-ui as peer dependency.

Theme UI with its 20.3kB gzipped (okay, it’s treeshakable but still) may be too big to use as a hidden dependency. Due to component libraries hiding their dep on styling libraries, big applications often end up with multiple styling libs in the bundle (I once had styled-components, emotion and goober).

Since Theme UI uses React context for theming, the theme for your component library can be overriden by your user. I find it nice to be frank about it and advertise it as a feature instead of a surprising bug.

Both React context and JSX types make Theme UI hard to hide.

Workaround 2

Make sure Props are not inlined with interface keyword.

Type aliases can be inlined during the build.

We can use interface keyword and export our props. This is generally a good idea. They’re public anyway and they can be accessed with React.ComponentProps<typeof Button>, but exporting ButtonProps for convenience is quite nice IMO.

import React, { ButtonHTMLAttributes } from 'react';

export interface ButtonProps
  extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'className'> {}

export const Button = React.forwardRef<HTMLButtonElement, Props>(props => {
  return <button {...props}
});

I’d prefer interface for library public API, because it introduces a named type (which won’t get inlined), allows declaration merging, and error messages with them are more succint and thus less scary.

https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases

Read more comments on GitHub >

github_iconTop Results From Across the Web

React with Typescript - Type { } is missing the following ...
As you are passing card to ProfileCard component, its passing 4 values in props. {login: string, name: string, key: number, id: number}.
Read more >
Error Ts2739: Type '{}' Is Missing The Following Properties ...
Got TS 2739 error while returning value from promise. Type [] is missing the following properties from type Pick<ButtonHTMLAttributes,[]: css I would be...
Read more >
Solved - Type x is missing the following properties from type y ...
This error occurs when you are not passing all the required props or only passing some of the required props to the component....
Read more >
the expected type comes from property 'style' which is ...
CSSProperties , it expects flexDirection to be of type FlexDirection , which is an union type ... Type 'Event' is missing the following...
Read more >
The sx prop - MUI System
You can specify any valid CSS using this prop, as well as many theme-aware properties that are unique to MUI System. Basic example....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found