Skip to content

Commit

Permalink
Reorder Styles (and Related) Generic Parameters
Browse files Browse the repository at this point in the history
* Styles (and related) generic type parameters are now ordered as
  `<Name, Props, Theme>`.
* Updated tests.
* Added `withStyles` test for plain objects without typedefs.
  • Loading branch information
ITenthusiasm committed Mar 10, 2021
1 parent bc118e9 commit 9d0eb91
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 35 deletions.
8 changes: 4 additions & 4 deletions packages/jss/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export type JssStyle<Props = any, Theme = undefined> =
}

export type Styles<
Name extends string | number | symbol = string,
Props = unknown,
Theme = undefined,
Name extends string | number | symbol = string
Theme = undefined
> = Record<
Name,
| JssStyle<Props, Theme>
Expand Down Expand Up @@ -219,7 +219,7 @@ export interface StyleSheet<RuleName extends string | number | symbol = string |
* Will render also after Style Sheet was rendered the first time.
*/
addRules(
styles: Partial<Styles<any, undefined, RuleName>>,
styles: Partial<Styles<RuleName, any, undefined>>,
options?: Partial<RuleOptions>
): Rule[]
/**
Expand Down Expand Up @@ -256,7 +256,7 @@ export interface JssOptions {

export interface Jss {
createStyleSheet<Name extends string | number | symbol>(
styles: Partial<Styles<any, undefined, Name>>,
styles: Partial<Styles<Name, any, undefined>>,
options?: StyleSheetFactoryOptions
): StyleSheet<Name>
removeStyleSheet(sheet: StyleSheet): this
Expand Down
6 changes: 3 additions & 3 deletions packages/jss/tests/types/Styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ declare const style$: Observable<{
}>

// General Types Check
const styles: Styles<Props> = {
const styles: Styles<string, Props> = {
basic: {
textAlign: 'center',
display: 'flex',
Expand Down Expand Up @@ -75,7 +75,7 @@ const styles: Styles<Props> = {

// Test supplied Props and Theme
// Verify that nested parameter declarations are banned
const stylesPropsAndTheme: Styles<Props, Theme> = {
const stylesPropsAndTheme: Styles<string, Props, Theme> = {
rootParamDeclaration: ({flag, theme}) => ({
fontWeight: 'bold',
// @ts-expect-error
Expand All @@ -93,7 +93,7 @@ const stylesPropsAndTheme: Styles<Props, Theme> = {
}

// Test the className types
const stylesClassNames: Styles<unknown, unknown, number> = {
const stylesClassNames: Styles<number, unknown, unknown> = {
// @ts-expect-error
stringClassName: '',
[1]: '',
Expand Down
18 changes: 9 additions & 9 deletions packages/react-jss/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ declare const JssContext: Context<{
}>

type ClassesForStyles<
S extends Styles<any, any, any> | ((theme: any) => Styles<any, undefined, any>)
> = Classes<S extends (theme: any) => Styles<any, undefined, any> ? keyof ReturnType<S> : keyof S>
S extends Styles<any, any, any> | ((theme: any) => Styles<any, any, undefined>)
> = Classes<S extends (theme: any) => Styles<any, any, undefined> ? keyof ReturnType<S> : keyof S>

interface WithStylesProps<
S extends Styles<any, any, any> | ((theme: any) => Styles<any, undefined, any>)
S extends Styles<any, any, any> | ((theme: any) => Styles<any, any, undefined>)
> {
classes: ClassesForStyles<S>
}
/**
* @deprecated Please use `WithStylesProps` instead
*/
type WithStyles<
S extends Styles<any, any, any> | ((theme: any) => Styles<any, undefined, any>)
S extends Styles<any, any, any> | ((theme: any) => Styles<any, any, undefined>)
> = WithStylesProps<S>

declare global {
Expand All @@ -76,17 +76,17 @@ interface CreateUseStylesOptions<Theme = DefaultTheme> extends BaseOptions<Theme
name?: string
}

declare function createUseStyles<Props = unknown, Theme = DefaultTheme, C extends string = string>(
styles: Styles<Props, Theme, C> | ((theme: Theme) => Styles<Props, undefined, C>),
declare function createUseStyles<C extends string = string, Props = unknown, Theme = DefaultTheme>(
styles: Styles<C, Props, Theme> | ((theme: Theme) => Styles<C, Props, undefined>),
options?: CreateUseStylesOptions<Theme>
): (data?: Props & {theme?: Theme}) => Classes<C>

type GetProps<C> = C extends ComponentType<infer P> ? P : never

declare function withStyles<Props, Theme, ClassNames extends string | number | symbol>(
declare function withStyles<ClassNames extends string | number | symbol, Props, Theme>(
styles:
| Styles<Props, Theme, ClassNames>
| ((theme: Theme) => Styles<Props, undefined, ClassNames>),
| Styles<ClassNames, Props, Theme>
| ((theme: Theme) => Styles<ClassNames, Props, undefined>),
options?: WithStylesOptions
): <C>(
comp: C
Expand Down
16 changes: 8 additions & 8 deletions packages/react-jss/tests/types/createUseStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const themeArg2ClassesFail2 = themeArg2({theme: expectedCustomTheme})
const themeArg2ClassesPass = themeArg2({theme: expectedDefaultTheme})

// Props declaration is allowed
const themeArg3 = createUseStyles<MyProps>(theme => ({
const themeArg3 = createUseStyles<string, MyProps>(theme => ({
onlyPropsAllowed: ({...props}) => ({
fontWeight: 'bold'
})
Expand All @@ -52,7 +52,7 @@ const themeArg3ClassesPass = themeArg3(expectedCustomProps)
const themeArg3ClassesPass2 = themeArg3({...expectedCustomProps, theme: expectedDefaultTheme})

// Nested props declaration banned
const themeArg4 = createUseStyles<MyProps>(theme => ({
const themeArg4 = createUseStyles<string, MyProps>(theme => ({
onlyPropsAllowed: ({...props}) => ({
fontWeight: 'bold',
// @ts-expect-error
Expand All @@ -61,7 +61,7 @@ const themeArg4 = createUseStyles<MyProps>(theme => ({
}))

// Supplied theme type is acknowledged
const themeArg5 = createUseStyles<unknown, MyTheme>(theme => ({}))
const themeArg5 = createUseStyles<string, unknown, MyTheme>(theme => ({}))
// @ts-expect-error
const themeArg5ClassesFail = themeArg5({theme: {}})
// @ts-expect-error
Expand Down Expand Up @@ -129,7 +129,7 @@ const noThemeArg2ClassesFail2 = noThemeArg2({theme: expectedCustomTheme})
const noThemeArg2ClassesPass = noThemeArg2({theme: expectedDefaultTheme})

// Props declaration is allowed, but not nested props declaration
const noThemeArg3 = createUseStyles<MyProps>({
const noThemeArg3 = createUseStyles<string, MyProps>({
propsAndTheme: ({property, theme}) => ({
fontWeight: 'bold',
// @ts-expect-error
Expand All @@ -149,7 +149,7 @@ const noThemeArg3ClassesPass = noThemeArg3(expectedCustomProps)
const noThemeArg3ClassesPass2 = noThemeArg3({...expectedCustomProps, theme: expectedDefaultTheme})

// Props and Theme types are properly acknowledged when supplied
const noThemeArg4 = createUseStyles<MyProps, MyTheme>({
const noThemeArg4 = createUseStyles<string, MyProps, MyTheme>({
propsAndTheme: ({property, theme}) => ({
fontWeight: 'bold',
// @ts-expect-error
Expand All @@ -169,7 +169,7 @@ const noThemeArg4ClassesPass = noThemeArg4(expectedCustomProps)
const noThemeArg4ClassesPass2 = noThemeArg4({...expectedCustomProps, theme: expectedCustomTheme})

// Nested declarations are banned (single nest test)
const noThemeArg5 = createUseStyles<MyProps, MyTheme>({
const noThemeArg5 = createUseStyles<string, MyProps, MyTheme>({
singleNest: {
fontWeight: 'bold',
singleValue: ({property, theme}) => '',
Expand All @@ -182,7 +182,7 @@ const noThemeArg5 = createUseStyles<MyProps, MyTheme>({
})

// Nested declarations are banned (double nest test)
const noThemeArg6 = createUseStyles<MyProps, MyTheme>({
const noThemeArg6 = createUseStyles<string, MyProps, MyTheme>({
doubleNest: {
fontWeight: 'bold',
singleValue: ({property, theme}) => '',
Expand All @@ -199,7 +199,7 @@ const noThemeArg6 = createUseStyles<MyProps, MyTheme>({
})

// Nested declarations are banned (triple nest test)
const noThemeArg7 = createUseStyles<MyProps, MyTheme>({
const noThemeArg7 = createUseStyles<string, MyProps, MyTheme>({
tripleNest: {
fontWeight: 'bold',
singleValue: ({property, theme}) => '',
Expand Down
43 changes: 32 additions & 11 deletions packages/react-jss/tests/types/withStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,32 @@ let ResultingComponent: React.ComponentType<MyProps>
let ComponentTest: React.FC

/* -------------------- Function Argument Passing Cases -------------------- */
// Plain Object (no type supplied)
function functionPlainObject(theme: MyTheme) {
return {
someClassName: '',
anotherClassName: {
fontWeight: 'bold'
}
}
}
ResultingComponent = withStyles(functionPlainObject)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// Plain Styles
function functionPlain(theme: MyTheme): Styles {
function functionPlainStyles(theme: MyTheme): Styles {
return {
someClassName: '',
anotherClassName: {
fontWeight: 'bold'
}
}
}
ResultingComponent = withStyles(functionPlain)(SimpleComponent)
ResultingComponent = withStyles(functionPlainStyles)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// With Props
function functionProps(theme: MyTheme): Styles<MyProps> {
function functionProps(theme: MyTheme): Styles<string, MyProps> {
return {
someClassName: ({property}) => '',
anotherClassName: {
Expand All @@ -50,7 +61,7 @@ ResultingComponent = withStyles(functionProps)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// With Props and ClassName rules
function functionPropsAndName(theme: MyTheme): Styles<MyProps, undefined, number> {
function functionPropsAndName(theme: MyTheme): Styles<number, MyProps, undefined> {
return {
[1]: ({property}) => '',
[2]: {
Expand All @@ -63,6 +74,16 @@ ComponentTest = () => <ResultingComponent property="" />

/* -------------------- Regular Object Passing Cases -------------------- */

// Plain Object (no type supplied)
const plainObject = {
someClassName: '',
anotherClassName: {
fontWeight: 'bold'
}
}
ResultingComponent = withStyles(plainObject)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// Plain Styles
const stylesPlain: Styles = {
someClassName: '',
Expand All @@ -74,7 +95,7 @@ ResultingComponent = withStyles(stylesPlain)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// With Props
const stylesProps: Styles<MyProps> = {
const stylesProps: Styles<string, MyProps> = {
someClassName: ({property}) => '',
anotherClassName: {
fontWeight: 'bold'
Expand All @@ -84,7 +105,7 @@ ResultingComponent = withStyles(stylesProps)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// With Theme
const stylesTheme: Styles<unknown, MyTheme> = {
const stylesTheme: Styles<string, unknown, MyTheme> = {
someClassName: ({theme}) => '',
anotherClassName: {
fontWeight: 'bold'
Expand All @@ -94,7 +115,7 @@ ResultingComponent = withStyles(stylesTheme)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// With Props and Theme
const stylesPropsAndTheme: Styles<MyProps, MyTheme> = {
const stylesPropsAndTheme: Styles<string, MyProps, MyTheme> = {
someClassName: ({property, theme}) => '',
anotherClassName: {
fontWeight: 'bold'
Expand All @@ -104,7 +125,7 @@ ResultingComponent = withStyles(stylesPropsAndTheme)(SimpleComponent)
ComponentTest = () => <ResultingComponent property="" />

// With Props and Theme and ClassName rules
const stylesPropsAndThemeAndName: Styles<MyProps, MyTheme, number> = {
const stylesPropsAndThemeAndName: Styles<number, MyProps, MyTheme> = {
[1]: ({property, theme}) => '',
[2]: {
fontWeight: 'bold'
Expand All @@ -116,7 +137,7 @@ ComponentTest = () => <ResultingComponent property="" />
/* -------------------- Failing Cases -------------------- */

// A function argument cannot provide another defined theme type conflicting with `undefined`
function failingFunctionRedefineTheme(theme: MyTheme): Styles<unknown, any> {
function failingFunctionRedefineTheme(theme: MyTheme): Styles<string, unknown, any> {
return {
someClassName: '',
anotherClassName: {
Expand All @@ -125,7 +146,7 @@ function failingFunctionRedefineTheme(theme: MyTheme): Styles<unknown, any> {
}
}

function passingFunctionUnknownTheme(theme: MyTheme): Styles<unknown, unknown> {
function passingFunctionUnknownTheme(theme: MyTheme): Styles<string, unknown, unknown> {
return {
someClassName: '',
anotherClassName: {
Expand All @@ -134,7 +155,7 @@ function passingFunctionUnknownTheme(theme: MyTheme): Styles<unknown, unknown> {
}
}

function passingFunctionNullTheme(theme: MyTheme): Styles<unknown, null> {
function passingFunctionNullTheme(theme: MyTheme): Styles<string, unknown, null> {
return {
someClassName: '',
anotherClassName: {
Expand Down

0 comments on commit 9d0eb91

Please sign in to comment.