1

I am using typescript,react.
I want to adapt each px size when one of xs, sm, md, lg is passed in props.
I used Record as follows, but I get a typescript error.

tsError

Type 'string | undefined' does not satisfy the constraint 'string | number | symbol'.
  Type 'undefined' is not assignable to type 'string | number | symbol'.ts(2344)
export type IconProps = {
  fontSize?: 'xs' | 'sm' | 'md' | 'lg';
  padding?: number;
  margin?: number;
};

export const FONTSIZE: Record<IconProps['fontSize'], string> = {
  xs: '14px',
  sm: '16px',
  md: '18px',
  lg: '24px',
};

import { Icon } from '@chakra-ui/react';
import React from 'react';
import { IconProps, FONTSIZE } from '../theme/iconProps';


export const ArrowRightIcon: React.FunctionComponent<IconProps> = ({
  fontSize,
  ...props
}) => {
  return (
    <Icon fontSize={FONTSIZE[fontSize]} {...props}>
      <path d="" /> // Abbreviation
    </Icon>
  );
};

2 Answers 2

3

IconProps['fontSize'] is optional. It means the value could be undefined. However, undefined could not be a key of the object. You can use Required to exclude the undefined situation of IconProps.

export const FONTSIZE: Record<Required<IconProps>['fontSize'], string> = {
  xs: '14px',
  sm: '16px',
  md: '18px',
  lg: '24px',
};
Sign up to request clarification or add additional context in comments.

Comments

2
fontSize?: 'xs' | 'sm' | 'md' | 'lg';

One of the possible values here is undefined, due to the ? which makes it optional. But undefined can't be the key of an object, so when you try to make a record with these as the keys, typescript complains.

You can exclude undefined by using NonNullable:

export const FONTSIZE: Record<NonNullable<IconProps['fontSize']>, string> = {
  xs: '14px',
  sm: '16px',
  md: '18px',
  lg: '24px',
};

Or if you prefer, Exclude is another option:

export const FONTSIZE: Record<Exclude<IconProps['fontSize'], undefined>, string> = {
  xs: '14px',
  sm: '16px',
  md: '18px',
  lg: '24px',
};

Playground Link

Comments

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.