Skip to content

Commit 62f0791

Browse files
Add more explicit types for the default theme (#8780)
* Add more explicit types for the default theme * Update changelog * Cleanup * Cleanup code a bit * Add special cases for a few keys * Fix order
1 parent 6e75e6e commit 62f0791

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
- Don’t prefix selectors in arbitrary variants ([#8773](https://github.com/tailwindlabs/tailwindcss/pull/8773))
1616
- Add support for alpha values in safe list ([#8774](https://github.com/tailwindlabs/tailwindcss/pull/8774))
1717
- Support default `font-weight`s in font size utilities ([#8763](https://github.com/tailwindlabs/tailwindcss/pull/8763))
18+
- Add more explicit types for the default theme ([#8780](https://github.com/tailwindlabs/tailwindcss/pull/8780))
1819

1920
## [3.1.4] - 2022-06-21
2021

defaultTheme.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import type { Config } from './types/config'
2-
declare const theme: Config['theme']
2+
import { DefaultTheme } from './types/generated/default-theme'
3+
declare const theme: Config['theme'] & DefaultTheme
34
export = theme

scripts/generate-types.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import prettier from 'prettier'
22
import { corePlugins } from '../src/corePlugins'
33
import colors from '../src/public/colors'
4+
import defaultTheme from '../src/public/default-theme'
45
import fs from 'fs'
56
import path from 'path'
7+
import * as types from './type-utils'
68

79
fs.writeFileSync(
810
path.join(process.cwd(), 'types', 'generated', 'corePluginList.d.ts'),
@@ -50,3 +52,54 @@ fs.writeFileSync(
5052
}
5153
)
5254
)
55+
56+
const defaultThemeTypes = Object.entries(defaultTheme)
57+
.map(([name, value]) => {
58+
// Special cases for slightly more accurate types
59+
if (name === 'keyframes') {
60+
return [name, `Record<${types.forKeys(value)}, Record<string, CSSDeclarationList>>`]
61+
}
62+
63+
if (name === 'fontSize') {
64+
return [name, `Record<${types.forKeys(value)}, [string, { lineHeight: string }]>`]
65+
}
66+
67+
// General cases
68+
if (typeof value === 'string') {
69+
return [name, `string`]
70+
}
71+
72+
if (typeof value === 'function') {
73+
return [name, null]
74+
}
75+
76+
if (typeof value === 'object') {
77+
if (Object.keys(value).length === 0) {
78+
return [name, null]
79+
}
80+
81+
return [name, types.forValue(value)]
82+
}
83+
84+
return [name, `unknown`]
85+
})
86+
.filter(([, type]) => type !== null)
87+
.map(([name, type]) => `${name}: ${type}`)
88+
.join('\n')
89+
90+
fs.writeFileSync(
91+
path.join(process.cwd(), 'types', 'generated', 'default-theme.d.ts'),
92+
prettier.format(
93+
`
94+
import { Config } from '../../types'
95+
type CSSDeclarationList = Record<string, string>
96+
export type DefaultTheme = Config['theme'] & { ${defaultThemeTypes} }
97+
`,
98+
{
99+
semi: false,
100+
singleQuote: true,
101+
printWidth: 100,
102+
parser: 'typescript',
103+
}
104+
)
105+
)

scripts/type-utils.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export function union(types) {
2+
return [...new Set(types)].join(' | ')
3+
}
4+
5+
export function unionValues(values) {
6+
return union(values.map(forValue))
7+
}
8+
9+
export function forKeys(value) {
10+
return union(Object.keys(value).map((key) => `'${key}'`))
11+
}
12+
13+
export function forValue(value) {
14+
if (Array.isArray(value)) {
15+
return `(${unionValues(value)})[]`
16+
}
17+
18+
if (typeof value === 'object') {
19+
return `Record<${forKeys(value)}, ${unionValues(Object.values(value))}>`
20+
}
21+
22+
if (typeof value === 'string') {
23+
return `string`
24+
}
25+
26+
return `any`
27+
}

0 commit comments

Comments
 (0)