diff --git a/.changeset/curly-houses-jump.md b/.changeset/curly-houses-jump.md new file mode 100644 index 000000000..faf334bd8 --- /dev/null +++ b/.changeset/curly-houses-jump.md @@ -0,0 +1,6 @@ +--- +'@emotion/styled': patch +'@emotion/react': patch +--- + +Improved compatibility with the upcoming `@types/react` for React 19 where the global `JSX` namespace doesn't exist anymore diff --git a/.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch b/.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch new file mode 100644 index 000000000..c94388186 --- /dev/null +++ b/.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch @@ -0,0 +1,17 @@ +diff --git a/dist/lint.js b/dist/lint.js +index ae29f2a0936fe8e4dee9b4a607ed5c611872d30d..96746c55f2df24c6d09ee30ff85e404138ad0fbe 100644 +--- a/dist/lint.js ++++ b/dist/lint.js +@@ -107,9 +107,9 @@ function startsWithDirectory(filePath, dirPath) { + return normalFilePath.startsWith(normalDirPath + "/") || normalFilePath.startsWith(normalDirPath + "\\"); + } + function testNoTsIgnore(text) { +- const tsIgnore = "ts-ignore"; +- const pos = text.indexOf(tsIgnore); +- return pos === -1 ? undefined : { pos, message: "'ts-ignore' is forbidden." }; ++ // const tsIgnore = "ts-ignore"; ++ // const pos = text.indexOf(tsIgnore); ++ // return pos === -1 ? undefined : { pos, message: "'ts-ignore' is forbidden." }; + } + function testNoTslintDisables(text) { + const tslintDisable = "tslint:disable"; diff --git a/package.json b/package.json index 303e120f2..c7be03a24 100644 --- a/package.json +++ b/package.json @@ -184,7 +184,7 @@ "@testing-library/react": "13.0.0-alpha.5", "@types/jest": "^29.5.12", "@types/node": "^12.20.37", - "@types/react": "^18.0.9", + "@types/react": "18.2.6", "@typescript-eslint/eslint-plugin": "^7.13.0", "@typescript-eslint/parser": "^7.13.0", "babel-check-duplicated-nodes": "^1.0.0", @@ -239,5 +239,8 @@ "unified": "^6.1.6", "webpack-bundle-analyzer": "3.3.2" }, - "packageManager": "yarn@3.2.3" + "packageManager": "yarn@3.2.3", + "resolutions": { + "@definitelytyped/dtslint@0.0.112": "patch:@definitelytyped/dtslint@npm%3A0.0.112#./.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch" + } } diff --git a/packages/native/types/tslint.json b/packages/native/types/tslint.json index 9828e9521..d3d5f2c1b 100644 --- a/packages/native/types/tslint.json +++ b/packages/native/types/tslint.json @@ -20,6 +20,7 @@ "no-null-undefined-union": false, "no-unnecessary-generics": false, "strict-export-declare-modifiers": false, - "unnecessary-bind": false + "unnecessary-bind": false, + "ban-ts-ignore": false } } diff --git a/packages/react/types/helper.d.ts b/packages/react/types/helper.d.ts index a2fc9b472..592bd3e7f 100644 --- a/packages/react/types/helper.d.ts +++ b/packages/react/types/helper.d.ts @@ -1,12 +1,12 @@ -import * as React from 'react' +import { ReactJSX } from './jsx-namespace' /** * @desc Utility type for getting props type of React component. * It takes `defaultProps` into an account - making props with defaults optional. */ export type PropsOf< - C extends keyof JSX.IntrinsicElements | React.JSXElementConstructor -> = JSX.LibraryManagedAttributes> + C extends keyof ReactJSX.IntrinsicElements | React.JSXElementConstructor +> = ReactJSX.LibraryManagedAttributes> // We need to use this version of Omit as it's distributive (Will preserve unions) export type DistributiveOmit = T extends any diff --git a/packages/react/types/jsx-namespace.d.ts b/packages/react/types/jsx-namespace.d.ts index f054601e5..b43dc4fa0 100644 --- a/packages/react/types/jsx-namespace.d.ts +++ b/packages/react/types/jsx-namespace.d.ts @@ -2,25 +2,81 @@ import 'react' import { Interpolation } from '@emotion/serialize' import { Theme } from '@emotion/react' +type IsPreReact19 = 2 extends Parameters>['length'] + ? true + : false + type WithConditionalCSSProp

= 'className' extends keyof P ? string extends P['className' & keyof P] ? { css?: Interpolation } : {} : {} -// unpack all here to avoid infinite self-referencing when defining our own JSX namespace -type ReactJSXElement = JSX.Element -type ReactJSXElementClass = JSX.ElementClass -type ReactJSXElementAttributesProperty = JSX.ElementAttributesProperty -type ReactJSXElementChildrenAttribute = JSX.ElementChildrenAttribute -type ReactJSXLibraryManagedAttributes = JSX.LibraryManagedAttributes -type ReactJSXIntrinsicAttributes = JSX.IntrinsicAttributes -type ReactJSXIntrinsicClassAttributes = JSX.IntrinsicClassAttributes -type ReactJSXIntrinsicElements = JSX.IntrinsicElements - -// based on the code from @types/react@18.2.8 -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3197efc097d522c4bf02b94e1a0766d007d6cdeb/types/react/index.d.ts#LL3204C13-L3204C13 -type ReactJSXElementType = string | React.JSXElementConstructor +// unpack all here to avoid infinite self-referencing when defining our own JSX namespace for the pre-React 19 case +type ReactJSXElement = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.Element + : /** @ts-ignore */ + React.JSX.Element +type ReactJSXElementClass = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.ElementClass + : /** @ts-ignore */ + React.JSX.ElementClass +type ReactJSXElementAttributesProperty = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.ElementAttributesProperty + : /** @ts-ignore */ + React.JSX.ElementAttributesProperty +type ReactJSXElementChildrenAttribute = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.ElementChildrenAttribute + : /** @ts-ignore */ + React.JSX.ElementChildrenAttribute +type ReactJSXLibraryManagedAttributes = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.LibraryManagedAttributes + : /** @ts-ignore */ + React.JSX.LibraryManagedAttributes +type ReactJSXIntrinsicAttributes = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.IntrinsicAttributes + : /** @ts-ignore */ + React.JSX.IntrinsicAttributes +type ReactJSXIntrinsicClassAttributes = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.IntrinsicClassAttributes + : /** @ts-ignore */ + React.JSX.IntrinsicClassAttributes +type ReactJSXIntrinsicElements = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.IntrinsicElements + : /** @ts-ignore */ + React.JSX.IntrinsicElements + +type ReactJSXElementType = true extends IsPreReact19 + ? // based on the code from @types/react@18.2.8 + // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3197efc097d522c4bf02b94e1a0766d007d6cdeb/types/react/index.d.ts#LL3204C13-L3204C13 + string | React.JSXElementConstructor + : /** @ts-ignore */ + React.JSX.ElementType + +export namespace ReactJSX { + type ElementType = ReactJSXElementType + interface Element extends ReactJSXElement {} + interface ElementClass extends ReactJSXElementClass {} + interface ElementAttributesProperty + extends ReactJSXElementAttributesProperty {} + interface ElementChildrenAttribute extends ReactJSXElementChildrenAttribute {} + + type LibraryManagedAttributes = ReactJSXLibraryManagedAttributes + + interface IntrinsicAttributes extends ReactJSXIntrinsicAttributes {} + interface IntrinsicClassAttributes + extends ReactJSXIntrinsicClassAttributes {} + + type IntrinsicElements = ReactJSXIntrinsicElements +} export namespace EmotionJSX { type ElementType = ReactJSXElementType diff --git a/packages/react/types/tslint.json b/packages/react/types/tslint.json index 114a734ad..d9d94bc9d 100644 --- a/packages/react/types/tslint.json +++ b/packages/react/types/tslint.json @@ -23,6 +23,7 @@ "no-unnecessary-generics": false, "no-empty-interface": false, "strict-export-declare-modifiers": false, - "unnecessary-bind": false + "unnecessary-bind": false, + "ban-ts-ignore": false } } diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index c75842c6f..c6533eec7 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -4,6 +4,7 @@ import * as React from 'react' import { ComponentSelector, Interpolation } from '@emotion/serialize' import { PropsOf, Theme } from '@emotion/react' +import { ReactJSXIntrinsicElements } from './jsx-namespace' export { ArrayInterpolation, @@ -49,9 +50,9 @@ export interface StyledComponent< withComponent>>( component: C ): StyledComponent> - withComponent( + withComponent( tag: Tag - ): StyledComponent + ): StyledComponent } /** @@ -169,23 +170,26 @@ export interface CreateStyled { > < - Tag extends keyof JSX.IntrinsicElements, - ForwardedProps extends keyof JSX.IntrinsicElements[Tag] & - string = keyof JSX.IntrinsicElements[Tag] & string + Tag extends keyof ReactJSXIntrinsicElements, + ForwardedProps extends keyof ReactJSXIntrinsicElements[Tag] & + string = keyof ReactJSXIntrinsicElements[Tag] & string >( tag: Tag, - options: FilteringStyledOptions + options: FilteringStyledOptions< + ReactJSXIntrinsicElements[Tag], + ForwardedProps + > ): CreateStyledComponent< { theme?: Theme; as?: React.ElementType }, - Pick + Pick > - ( + ( tag: Tag, - options?: StyledOptions + options?: StyledOptions ): CreateStyledComponent< { theme?: Theme; as?: React.ElementType }, - JSX.IntrinsicElements[Tag] + ReactJSXIntrinsicElements[Tag] > } diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index 883a79ea0..28ef9a2d4 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -3,6 +3,7 @@ import { Theme } from '@emotion/react' import { CreateStyled as BaseCreateStyled, CreateStyledComponent } from './base' +import { ReactJSXIntrinsicElements } from './jsx-namespace' export { ArrayInterpolation, @@ -17,12 +18,12 @@ export { } from './base' export type StyledTags = { - [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent< + [Tag in keyof ReactJSXIntrinsicElements]: CreateStyledComponent< { theme?: Theme as?: React.ElementType }, - JSX.IntrinsicElements[Tag] + ReactJSXIntrinsicElements[Tag] > } diff --git a/packages/styled/types/jsx-namespace.d.ts b/packages/styled/types/jsx-namespace.d.ts new file mode 100644 index 000000000..a45d7c3c2 --- /dev/null +++ b/packages/styled/types/jsx-namespace.d.ts @@ -0,0 +1,14 @@ +// this is basically a slimmed down copy of https://github.com/emotion-js/emotion/blob/main/packages/react/types/jsx-namespace.d.ts +// it helps to avoid issues when combining newer `@emotion/styled` and older `@emotion/react` versions +// in such setup, ReactJSX namespace won't exist in `@emotion/react` and that would lead to errors +import 'react' + +type IsPreReact19 = 2 extends Parameters>['length'] + ? true + : false + +export type ReactJSXIntrinsicElements = true extends IsPreReact19 + ? /** @ts-ignore */ + JSX.IntrinsicElements + : /** @ts-ignore */ + React.JSX.IntrinsicElements diff --git a/packages/styled/types/tests.tsx b/packages/styled/types/tests.tsx index 24bed6fb1..bbfa2b27d 100644 --- a/packages/styled/types/tests.tsx +++ b/packages/styled/types/tests.tsx @@ -63,7 +63,7 @@ const Container3 = styled.div(({ theme }) => ({ const Box = styled('div', { shouldForwardProp: ( propName - ): propName is Exclude => + ): propName is Exclude => propName !== 'color' })<{ color: Array }>(props => ({ color: props.color[0] diff --git a/packages/styled/types/tslint.json b/packages/styled/types/tslint.json index 3c15806b7..5b9490dda 100644 --- a/packages/styled/types/tslint.json +++ b/packages/styled/types/tslint.json @@ -17,6 +17,9 @@ "check-preblock" ], "no-unnecessary-generics": false, - "unnecessary-bind": false + "unnecessary-bind": false, + "ban-ts-ignore": false, + "no-empty-interface": false, + "strict-export-declare-modifiers": false } } diff --git a/site/package.json b/site/package.json index 1b61696f3..217bc523f 100644 --- a/site/package.json +++ b/site/package.json @@ -19,7 +19,7 @@ "@types/js-yaml": "^4.0.5", "@types/node": "^12.20.37", "@types/prismjs": "^1.26.0", - "@types/react": "^18.0.9", + "@types/react": "18.2.6", "@types/remark-prism": "^1.3.3", "facepaint": "^1.2.1", "gray-matter": "^4.0.3", diff --git a/yarn.lock b/yarn.lock index 2d3914ab4..f5aa59fc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2580,6 +2580,27 @@ __metadata: languageName: node linkType: hard +"@definitelytyped/dtslint@patch:@definitelytyped/dtslint@npm%3A0.0.112#./.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch::locator=emotion-monorepo%40workspace%3A.": + version: 0.0.112 + resolution: "@definitelytyped/dtslint@patch:@definitelytyped/dtslint@npm%3A0.0.112#./.yarn/patches/@definitelytyped-dtslint-npm-0.0.112-1e6b842976.patch::version=0.0.112&hash=753776&locator=emotion-monorepo%40workspace%3A." + dependencies: + "@definitelytyped/dts-critic": ^0.0.112 + "@definitelytyped/header-parser": ^0.0.112 + "@definitelytyped/typescript-versions": ^0.0.112 + "@definitelytyped/utils": ^0.0.112 + fs-extra: ^6.0.1 + json-stable-stringify: ^1.0.1 + strip-json-comments: ^2.0.1 + tslint: 5.14.0 + yargs: ^15.1.0 + peerDependencies: + typescript: ">= 3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev || >= 3.8.0-dev || >= 3.9.0-dev || >= 4.0.0-dev" + bin: + dtslint: dist/index.js + checksum: 531e55134c34b4be44bd5aedb193b5dd99c098a374d1725e53bfc567a6bad8da6d314a7446f1480b2502afc6ed579555b4a8b31c40513f68dc7e679b51784c5f + languageName: node + linkType: hard + "@definitelytyped/header-parser@npm:^0.0.112": version: 0.0.112 resolution: "@definitelytyped/header-parser@npm:0.0.112" @@ -6354,14 +6375,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:>=16, @types/react@npm:^18.0.9": - version: 18.0.14 - resolution: "@types/react@npm:18.0.14" +"@types/react@npm:*, @types/react@npm:18.2.6, @types/react@npm:>=16": + version: 18.2.6 + resolution: "@types/react@npm:18.2.6" dependencies: "@types/prop-types": "*" "@types/scheduler": "*" csstype: ^3.0.2 - checksum: 608eb57a383eedc54c79949673e5e8314f6b0c61542bff58721c8c47a18c23e2832e77c656050c2c2c004b62cf25582136c7c56fe1b6263a285c065fae31dbcf + checksum: dea9d232d8df7ac357367a69dcb557711ab3d5501807ffa77cebeee73d49ee94d095f298e36853c63ed47cce097eee4c7eae2aaa8c02fac3f0171ec1b523a819 languageName: node linkType: hard @@ -12617,7 +12638,7 @@ __metadata: "@testing-library/react": 13.0.0-alpha.5 "@types/jest": ^29.5.12 "@types/node": ^12.20.37 - "@types/react": ^18.0.9 + "@types/react": 18.2.6 "@typescript-eslint/eslint-plugin": ^7.13.0 "@typescript-eslint/parser": ^7.13.0 babel-check-duplicated-nodes: ^1.0.0 @@ -12689,7 +12710,7 @@ __metadata: "@types/js-yaml": ^4.0.5 "@types/node": ^12.20.37 "@types/prismjs": ^1.26.0 - "@types/react": ^18.0.9 + "@types/react": 18.2.6 "@types/remark-prism": ^1.3.3 facepaint: ^1.2.1 gray-matter: ^4.0.3