Skip to content

Commit 39714ae

Browse files
authoredDec 22, 2023
Fix nested types output from createStrictAPI() being unintentionally marked as required (#1604)
* fix: nested types being unintentionally marked as required * fix: css map throwing invariant when no styles
1 parent da0c07e commit 39714ae

File tree

5 files changed

+69
-7
lines changed

5 files changed

+69
-7
lines changed
 

‎.changeset/kind-toys-roll.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/babel-plugin': patch
3+
---
4+
5+
cssMap() no longer throws an invariant if no styles were generated.

‎.changeset/sour-nails-breathe.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@compiled/react': patch
3+
---
4+
5+
Fix nested types being forcibly required.

‎packages/babel-plugin/src/css-map/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ export const visitCssMapPath = (
9898
const { sheets, classNames } = transformCssItems(css, meta);
9999
totalSheets.push(...sheets);
100100

101-
if (classNames.length !== 1) {
101+
if (classNames.length > 1) {
102102
throw buildCodeFrameError(
103103
createErrorMessage(ErrorMessages.STATIC_VARIANT_OBJECT),
104104
property,
105105
meta.parentPath
106106
);
107107
}
108108

109-
return t.objectProperty(property.key, classNames[0]);
109+
return t.objectProperty(property.key, classNames[0] || t.stringLiteral(''));
110110
})
111111
)
112112
);

‎packages/react/src/create-strict-api/__tests__/generics.test.tsx

+52
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,58 @@ import type { XCSSProp } from './__fixtures__/strict-api-recursive';
55
import { css, cssMap } from './__fixtures__/strict-api-recursive';
66

77
describe('createStrictAPI()', () => {
8+
it('should mark all styles as optional in css()', () => {
9+
const styles = css({
10+
'&:hover': {},
11+
'&:active': {},
12+
'&::before': {},
13+
'&::after': {},
14+
});
15+
16+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
17+
18+
expect(getByTestId('div')).toBeDefined();
19+
});
20+
21+
it('should mark all styles as optional in cssMap()', () => {
22+
const styles = cssMap({
23+
nested: {
24+
'&:hover': {},
25+
'&:active': {},
26+
'&::before': {},
27+
'&::after': {},
28+
},
29+
});
30+
31+
const { getByTestId } = render(<div css={styles.nested} data-testid="div" />);
32+
33+
expect(getByTestId('div')).toBeDefined();
34+
});
35+
36+
it('should mark all styles as optional in xcss prop', () => {
37+
function Component({
38+
xcss,
39+
}: {
40+
xcss: ReturnType<
41+
typeof XCSSProp<
42+
'backgroundColor' | 'color',
43+
'&:hover' | '&:active' | '&::before' | '&::after'
44+
>
45+
>;
46+
}) {
47+
return <div data-testid="div" className={xcss} />;
48+
}
49+
50+
const { getByTestId } = render(
51+
<Component
52+
xcss={{ '&:hover': {}, '&:active': {}, '&::before': {}, '&::after': {} }}
53+
data-testid="div"
54+
/>
55+
);
56+
57+
expect(getByTestId('div')).toBeDefined();
58+
});
59+
860
describe('type violations', () => {
961
it('should violate types for css()', () => {
1062
const styles = css({

‎packages/react/src/create-strict-api/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ type PseudosDeclarations = {
66
[Q in CSSPseudos]?: StrictCSSProperties;
77
};
88

9-
type EnforceSchema<TObject> = {
10-
[P in keyof TObject]?: P extends keyof CompiledSchema
11-
? TObject[P] extends Record<string, unknown>
12-
? EnforceSchema<TObject[P]>
13-
: TObject[P]
9+
type EnforceSchema<TSchema> = {
10+
[P in keyof TSchema]?: P extends keyof CompiledSchema
11+
? TSchema[P] extends Record<string, any>
12+
? EnforceSchema<TSchema[P]>
13+
: TSchema[P]
1414
: never;
1515
};
1616

0 commit comments

Comments
 (0)
Please sign in to comment.