TypeScript
@soroush.tech/styled-system ships its own first-class types - it replaces
@types/styled-system, and the public type surface matches @types/[email protected]
so existing typed code keeps compiling.
Typing component props
Every style function has a matching prop interface. Compose the ones you use into your
component's props. Each interface is generic over your Theme, so prop values are
scale-aware - they resolve to keys of the relevant theme scale.
import styled from '@emotion/styled'
import {
space,
color,
typography,
type SpaceProps,
type ColorProps,
type TypographyProps,
type Theme,
} from '@soroush.tech/styled-system'
const theme = {
space: [0, 4, 8, 16, 32, 64],
fontSizes: [12, 14, 16, 24, 32],
colors: { primary: '#0077cc', white: '#fff' },
} satisfies Theme
type AppTheme = typeof theme
type BoxProps = SpaceProps<AppTheme> & ColorProps<AppTheme> & TypographyProps<AppTheme>
const Box = styled('div')<BoxProps>(space, color, typography)
// `m` → space index, `bg`/`color` → colors keys, `fontSize` → fontSizes index.
// `bg="green"` would be a compile error - green isn't in the theme's colors.
;<Box m={2} bg="primary" color="white" fontSize={3} />
How scale-awareness works
SpaceProps<ThemeType, TVal = ThemeValue<'space', ThemeType>> derives the value type
TVal from the theme via the ThemeValue helper:
- array scale (
space: [...]) → the value type isnumber(an index) - object scale (
colors: { primary, ... }) → the value type is the key union
The seven scale-bound groups mirror @types/styled-system: space (SpaceProps,
MarginProps, PaddingProps), colors (ColorProps, BorderProps.borderColor),
fontSizes/fontWeights/lineHeights (TypographyProps), and radii
(BorderProps.borderRadius). Everything else is typed as the corresponding CSS property.
Prop interfaces exported: SpaceProps, MarginProps, PaddingProps, LayoutProps,
TypographyProps, FlexboxProps, PositionProps, ColorProps, BorderProps,
BackgroundProps, GridProps, ShadowProps, plus the foundation types Theme,
RequiredTheme, ResponsiveValue, ThemeValue, ObjectOrArray, TLengthStyledSystem.
Custom style functions are typed too
system() / createParser() / compose() return a Parser - a callable that drops
straight into Emotion's or styled-components' styled() as an interpolation. Its call
signature is currently loosened to (...args: any[]): any to match the original
@styled-system styleFn, so the style functions stay permissive interpolations on any
host element. A stricter <P extends { theme?: unknown }>(props: P) => CSSObject
signature is planned for a future major.
Drop-in for existing styled-system + @types/styled-system
Swap via a package-manager alias - no code or type changes:
"dependencies": {
"styled-system": "npm:@soroush.tech/styled-system@^5"
}
A runnable, tsc-verified example lives in
styled-system/typescript.