Skip to content

Commit a19d019

Browse files
authored
Convert @emotion/styled's source code to TypeScript (#3284)
* Convert `@emotion/styled`'s source code to TypeScript * fixed entrypoint extension * fix types reference * add changeset * more localized cast * remove redundant cast * organize imports
1 parent 5974e33 commit a19d019

File tree

19 files changed

+352
-393
lines changed

19 files changed

+352
-393
lines changed

β€Ž.changeset/metal-cups-allow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@emotion/styled': minor
3+
---
4+
5+
Source code has been migrated to TypeScript. From now on type declarations will be emitted based on that, instead of being hand-written.

β€Žpackages/serialize/src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,11 @@ export function serializeStyles(
398398
strings as Interpolation
399399
)
400400
} else {
401-
const asTemplateStringsArr = strings as TemplateStringsArray
402-
if (isDevelopment && asTemplateStringsArr[0] === undefined) {
401+
const templateStringsArr = strings as TemplateStringsArray
402+
if (isDevelopment && templateStringsArr[0] === undefined) {
403403
console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR)
404404
}
405-
styles += asTemplateStringsArr[0]
405+
styles += templateStringsArr[0]
406406
}
407407
// we start at 1 since we've already handled the first arg
408408
for (let i = 1; i < args.length; i++) {

β€Žpackages/styled/base/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"main": "dist/emotion-styled-base.cjs.js",
33
"module": "dist/emotion-styled-base.esm.js",
44
"umd:main": "dist/emotion-styled-base.umd.min.js",
5-
"types": "../types/base",
5+
"types": "dist/emotion-styled-base.cjs.d.ts",
66
"preconstruct": {
77
"umdName": "emotionStyledBase"
88
}

β€Žpackages/styled/package.json

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "styled API for emotion",
55
"main": "dist/emotion-styled.cjs.js",
66
"module": "dist/emotion-styled.esm.js",
7-
"types": "types/index.d.ts",
7+
"types": "dist/emotion-styled.cjs.d.ts",
88
"license": "MIT",
99
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/styled",
1010
"scripts": {
@@ -40,7 +40,6 @@
4040
"src",
4141
"dist",
4242
"base",
43-
"types/*.d.ts",
4443
"macro.*"
4544
],
4645
"umd:main": "dist/emotion-styled.umd.min.js",
@@ -164,22 +163,22 @@
164163
},
165164
"imports": {
166165
"#is-development": {
167-
"development": "./src/conditions/true.js",
168-
"default": "./src/conditions/false.js"
166+
"development": "./src/conditions/true.ts",
167+
"default": "./src/conditions/false.ts"
169168
},
170169
"#is-browser": {
171-
"edge-light": "./src/conditions/false.js",
172-
"workerd": "./src/conditions/false.js",
173-
"worker": "./src/conditions/false.js",
174-
"browser": "./src/conditions/true.js",
175-
"default": "./src/conditions/is-browser.js"
170+
"edge-light": "./src/conditions/false.ts",
171+
"workerd": "./src/conditions/false.ts",
172+
"worker": "./src/conditions/false.ts",
173+
"browser": "./src/conditions/true.ts",
174+
"default": "./src/conditions/is-browser.ts"
176175
}
177176
},
178177
"preconstruct": {
179178
"umdName": "emotionStyled",
180179
"entrypoints": [
181-
"./index.js",
182-
"./base.js"
180+
"./index.ts",
181+
"./base.tsx"
183182
],
184183
"exports": {
185184
"extra": {

β€Žpackages/styled/src/base.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

β€Žpackages/styled/src/base.js renamed to β€Žpackages/styled/src/base.tsx

Lines changed: 56 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,40 @@
1-
import * as React from 'react'
2-
import {
3-
getDefaultShouldForwardProp,
4-
composeShouldForwardProps
5-
/*
6-
type StyledOptions,
7-
type CreateStyled,
8-
type PrivateStyledComponent,
9-
type StyledElementType
10-
*/
11-
} from './utils'
12-
import { withEmotionCache, ThemeContext } from '@emotion/react'
13-
import isDevelopment from '#is-development'
141
import isBrowser from '#is-browser'
2+
import isDevelopment from '#is-development'
3+
import { Theme, ThemeContext, withEmotionCache } from '@emotion/react'
4+
import { Interpolation, serializeStyles } from '@emotion/serialize'
5+
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
156
import {
7+
EmotionCache,
168
getRegisteredStyles,
179
insertStyles,
18-
registerStyles
10+
registerStyles,
11+
SerializedStyles
1912
} from '@emotion/utils'
20-
import { serializeStyles } from '@emotion/serialize'
21-
import { useInsertionEffectAlwaysWithSyncFallback } from '@emotion/use-insertion-effect-with-fallbacks'
13+
import * as React from 'react'
14+
import { CreateStyled, ElementType, StyledOptions } from './types'
15+
import { composeShouldForwardProps, getDefaultShouldForwardProp } from './utils'
16+
export type {
17+
ArrayInterpolation,
18+
ComponentSelector,
19+
CSSObject,
20+
FunctionInterpolation,
21+
Interpolation
22+
} from '@emotion/serialize'
2223

2324
const ILLEGAL_ESCAPE_SEQUENCE_ERROR = `You have illegal escape sequence in your template literal, most likely inside content's property value.
2425
Because you write your CSS inside a JavaScript string you actually have to do double escaping, so for example "content: '\\00d7';" should become "content: '\\\\00d7';".
2526
You can read more about this here:
2627
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#ES2018_revision_of_illegal_escape_sequences`
2728

28-
const Insertion = ({ cache, serialized, isStringTag }) => {
29+
const Insertion = ({
30+
cache,
31+
serialized,
32+
isStringTag
33+
}: {
34+
cache: EmotionCache
35+
serialized: SerializedStyles
36+
isStringTag: boolean
37+
}) => {
2938
registerStyles(cache, serialized, isStringTag)
3039

3140
const rules = useInsertionEffectAlwaysWithSyncFallback(() =>
@@ -52,10 +61,7 @@ const Insertion = ({ cache, serialized, isStringTag }) => {
5261
return null
5362
}
5463

55-
let createStyled /*: CreateStyled */ = (
56-
tag /*: any */,
57-
options /* ?: StyledOptions */
58-
) => {
64+
const createStyled = (tag: ElementType, options?: StyledOptions) => {
5965
if (isDevelopment) {
6066
if (tag === undefined) {
6167
throw new Error(
@@ -66,8 +72,8 @@ let createStyled /*: CreateStyled */ = (
6672
const isReal = tag.__emotion_real === tag
6773
const baseTag = (isReal && tag.__emotion_base) || tag
6874

69-
let identifierName
70-
let targetClassName
75+
let identifierName: string | undefined
76+
let targetClassName: string | undefined
7177
if (options !== undefined) {
7278
identifierName = options.label
7379
targetClassName = options.target
@@ -78,9 +84,11 @@ let createStyled /*: CreateStyled */ = (
7884
shouldForwardProp || getDefaultShouldForwardProp(baseTag)
7985
const shouldUseAs = !defaultShouldForwardProp('as')
8086

81-
/* return function<Props>(): PrivateStyledComponent<Props> { */
8287
return function () {
83-
let args = arguments
88+
// eslint-disable-next-line prefer-rest-params
89+
let args = arguments as any as Array<
90+
TemplateStringsArray | Interpolation<Theme>
91+
>
8492
let styles =
8593
isReal && tag.__emotion_styles !== undefined
8694
? tag.__emotion_styles.slice(0)
@@ -89,29 +97,35 @@ let createStyled /*: CreateStyled */ = (
8997
if (identifierName !== undefined) {
9098
styles.push(`label:${identifierName};`)
9199
}
92-
if (args[0] == null || args[0].raw === undefined) {
100+
if (
101+
args[0] == null ||
102+
(args[0] as TemplateStringsArray).raw === undefined
103+
) {
104+
// eslint-disable-next-line prefer-spread
93105
styles.push.apply(styles, args)
94106
} else {
95-
if (isDevelopment && args[0][0] === undefined) {
107+
const templateStringsArr = args[0] as TemplateStringsArray
108+
if (isDevelopment && templateStringsArr[0] === undefined) {
96109
console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR)
97110
}
98-
styles.push(args[0][0])
111+
styles.push(templateStringsArr[0])
99112
let len = args.length
100113
let i = 1
101114
for (; i < len; i++) {
102-
if (isDevelopment && args[0][i] === undefined) {
115+
if (isDevelopment && templateStringsArr[i] === undefined) {
103116
console.error(ILLEGAL_ESCAPE_SEQUENCE_ERROR)
104117
}
105-
styles.push(args[i], args[0][i])
118+
styles.push(args[i], templateStringsArr[i])
106119
}
107120
}
108121

109-
const Styled /*: PrivateStyledComponent<Props> */ = withEmotionCache(
110-
(props, cache, ref) => {
111-
const FinalTag = (shouldUseAs && props.as) || baseTag
122+
const Styled: ElementType = withEmotionCache(
123+
(props: Record<string, unknown>, cache, ref) => {
124+
const FinalTag =
125+
(shouldUseAs && (props.as as React.ElementType)) || baseTag
112126

113127
let className = ''
114-
let classInterpolations = []
128+
let classInterpolations: Interpolation<Theme>[] = []
115129
let mergedProps = props
116130
if (props.theme == null) {
117131
mergedProps = {}
@@ -146,7 +160,7 @@ let createStyled /*: CreateStyled */ = (
146160
? getDefaultShouldForwardProp(FinalTag)
147161
: defaultShouldForwardProp
148162

149-
let newProps = {}
163+
let newProps: Record<string, unknown> = {}
150164

151165
for (let key in props) {
152166
if (shouldUseAs && key === 'as') continue
@@ -196,20 +210,20 @@ let createStyled /*: CreateStyled */ = (
196210
return `.${targetClassName}`
197211
}
198212
})
199-
200-
Styled.withComponent = (
201-
nextTag /*: StyledElementType<Props> */,
202-
nextOptions /* ?: StyledOptions */
213+
;(Styled as any).withComponent = (
214+
nextTag: ElementType,
215+
nextOptions: StyledOptions
203216
) => {
204-
return createStyled(nextTag, {
217+
const newStyled = createStyled(nextTag, {
205218
...options,
206219
...nextOptions,
207220
shouldForwardProp: composeShouldForwardProps(Styled, nextOptions, true)
208-
})(...styles)
221+
})
222+
return (newStyled as any)(...styles)
209223
}
210224

211225
return Styled
212226
}
213227
}
214228

215-
export default createStyled
229+
export default createStyled as CreateStyled

β€Žpackages/styled/src/index.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
Β (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy