Skip to content

Instantly share code, notes, and snippets.

@itsMapleLeaf
Last active January 5, 2019 01:09
Show Gist options
  • Save itsMapleLeaf/313a04d3bbf8b5e583a38acb426d77a2 to your computer and use it in GitHub Desktop.
Save itsMapleLeaf/313a04d3bbf8b5e583a38acb426d77a2 to your computer and use it in GitHub Desktop.
emotion styled property explanation

Simplified, styled.hr is typed to accept either a template string interpolation, or a valid style object.

In this case, a valid style object is that which borderTopStyle can only be one of many possible strings, specifically, the type 'solid' | '...'

However, TS' default behavior is to infer any objects' properties as string, and string is not assignable to 'solid' | '...'.

// obj.a is type "string" not type "'hello'"
const obj = { a: 'hello' }

const obj1: { a: string } = obj // passes
const obj2: { a: 'hello' } = obj // errors

Since it doesn't match a valid style object, TS moves onto the next possibility, a template string. It doesn't match that either, and it's run out of overloads, so it stops there and tells you what it couldn't find a match for. This is one place where TS' DX could certainly improve, by telling you all of the possibilities it couldn't match, as opposed to just the last one it sees.

Solution: declare the object type as what it should be, and TS will enforce/infer the string literal types. Here, it looks like CSSObject from @emotion/styled will do the trick.

import { CSSObject } from '@emotion/styled'

const baseStyles: CSSObject = { borderTopStyle: 'solid' }
const NotWorkingDivider = styled.hr(baseStyles)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment