Home > database >  Typescript error with custom Typography component
Typescript error with custom Typography component

Time:09-01

I have created a rather basic typography component for my React application and it's throwing a Typescript error which i must admit is baffling my slightly.

Typography Component Code

import clsx from 'clsx';

const variants = {
    h1: 'h1',
    h2: 'h2',
    h3: 'h2',
    h4: 'h2',
    h5: 'h2',
    h6: 'h2',
    subheading1: 'h6',
    subheading2: 'h6',
    body1: 'p',
    body2: 'p',
    link: 'p',
};

const typographyVariants = {
    h1: 'text-6xl',
    h2: 'text-5xl',
    h3: 'text-4xl',
    h4: 'text-3xl',
    h5: 'text-2xl',
    h6: 'text-1xl',
    subheading1: 'text-1xl font-bold',
    subheading2: 'text-1xl font-semibold',
    body1: 'text-base',
    body2: 'text-base font-bold',
    link: 'text-xs text-primaryViolet uppercase underline font-bold',
};

export type TypographyProps = {
    variant?: keyof typeof variants;
    className?: string;
    children: React.ReactNode | string;
};

export const Typography = ({ variant = 'body1', className, children }: TypographyProps) => {
    const Component = variants[variant];
    const typographyStyles = typographyVariants[variant];

    return (
        <Component className={clsx('font-sans', typographyStyles, className)}>{children}</Component>
    );
};

Typescript Error

The '<Component' bit in the return statment is highlighted with the following error

Type '{ children: ReactNode; className: string; }' is not assignable to type 'IntrinsicAttributes'. Property 'children' does not exist on type 'IntrinsicAttributes'.ts(2322)

Anyone have any ideas?

Thanks

Lee

CodePudding user response:

const variants = {
    h1: 'h1',
    h2: 'h2',
    h3: 'h2',
    h4: 'h2',
    h5: 'h2',
    h6: 'h2',
    subheading1: 'h6',
    subheading2: 'h6',
    body1: 'p',
    body2: 'p',
    link: 'p',
};

With no explicit type on this, typescript assigns string to all the properties, which means Component in const Component = variants[variant]; is also of type string. With a type that general, the only things you're allowed to pass in to <Component /> are ones that are shared by every single element. This is represented by a type called IntrinsicAttributes, and is just the key property. No children allowed, no className allowed.

You can fix this by being more explicit when defining variants. The simplest approach would just be to add as const to the end, so that typescript will be stricter in the definition that it infers:

const variants = {
    h1: 'h1',
    // ...
    link: 'p',
} as const;

With that change, Component now has the type "h1" | "h2" | "h6" | "p", and since all of those elements allow children and className, the type error will go away.

  • Related