Home > front end >  How to get CSS types for React / styled-components?
How to get CSS types for React / styled-components?

Time:01-13

I am getting this error in my styled component:

Type 'string | undefined' is not assignable to type 'WordBreak | undefined'.

It is happening here:

type PropsType = {
  breakEverywhere?: boolean
  breakWord?: boolean
}

const Text = styled.p<PropsType>(props => ({
  wordBreak: getWordBreak(props),
}))

function getWordBreak(props: PropsType): string | undefined {
  if (props.breakWord) {
    return 'break-word'
  }
  if (props.breakEverywhere) {
    return 'break-all'
  }
}

It can be easily fixed by leaving off the type annotation string | undefined on the getWordBreak function. But how can I add a type annotation? It says WordBreak, but google searching for WordBreak type definitions doesn't yield any results, and no VSCode help. Any ideas?

The same sort of problem happens if I abstract away textAlign to in a similar way, it talks about TextAlign type. Looks like the csstype won't help either.

If I use this in the styled component:

textAlign: props.align ? TEXT_ALIGN[props.align] : undefined,

And I have this:

type AlignType = 'center' | 'end' | 'start'

const TEXT_ALIGN: Record<AlignType, string> = {
  center: 'center',
  end: 'right',
  start: 'left',
}

Then i get this:

Types of property 'textAlign' are incompatible.
  Type 'string | undefined' is not assignable to type 'TextAlign | undefined'.
    Type 'string' is not assignable to type 'TextAlign | undefined'.ts(2345)

I can fix it with an untyped function instead:

function getTextAlign(align: AlignType) {
  switch (align) {
    case 'center':
      return 'center'
    case 'end':
      return 'right'
    default:
      return 'left'
  }
}

But that is ugly, how can I do it the Record way or a cleaner way? How can I get access to these types?

CodePudding user response:

Looks like the csstype won't help either.

Styled-components types are based on csstype, so you should be able to get what you need from there.

Type WordBreak is in namespace Property of csstype:

export namespace Property {
  // ...
  export type WordBreak = Globals | "break-all" | "break-word" | "keep-all" | "normal";
  // ...
}

Using it with your code sample:

const Text2 = styled.p<PropsType>(props => ({
    wordBreak: getWordBreak2(props), // Okay
}))

function getWordBreak2(props: PropsType): Property.WordBreak | undefined { // Okay
    if (props.breakWord) {
        return 'break-word'
    }
    if (props.breakEverywhere) {
        return 'break-all'
    }
    return
}

Playground Link

  • Related