Skip to content

Commit 02da2b8

Browse files
baffaloppfngaidakovRobinMalfait
authored
Improve resolveConfig return type: merge themes (#12272)
* Generate types: do not intersect with Config theme type when generating DefaultTheme * Merge default theme in ResolvedConfig * UnwrapResolvables on theme.extend as well * Apply extend to overrides and default theme * Omit extend from DefaultTheme * Relax generic constraints, better generic variable names * Fall back to ThemeConfig if key not in DefaultTheme * Split out ThemeConfigCustomizable to avoid anys in ThemeConfigResolved * Allow custom theme properties * handle TypeScript error * apply prettier formatting * update changelog * change type name --------- Co-authored-by: Nikita Gaidakov <[email protected]> Co-authored-by: Robin Malfait <[email protected]>
1 parent 782c733 commit 02da2b8

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Fallback to RegEx based parser when using custom transformers or extractors ([#11335](https://github.com/tailwindlabs/tailwindcss/pull/11335))
1515
- Bump `lightningcss` and reflect related improvements in tests ([#11550](https://github.com/tailwindlabs/tailwindcss/pull/11550))
1616
- Fix incorrect spaces around `-` in `calc()` expression ([#12283](https://github.com/tailwindlabs/tailwindcss/pull/12283))
17+
- Improve types for `resolveConfig` ([#12272](https://github.com/tailwindlabs/tailwindcss/pull/12272))
1718

1819
### Added
1920

resolveConfig.d.ts

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1-
import type { Config, ResolvableTo } from './types/config'
1+
import { Config, ResolvableTo, ThemeConfig } from './types/config'
2+
import { DefaultTheme } from './types/generated/default-theme'
3+
import { DefaultColors } from './types/generated/colors'
4+
5+
type ResolvedConfig<T extends Config> = Omit<T, 'theme'> & {
6+
theme: MergeThemes<
7+
UnwrapResolvables<Omit<T['theme'], 'extend'>>,
8+
T['theme'] extends { extend: infer TExtend } ? UnwrapResolvables<TExtend> : {}
9+
>
10+
}
211

312
type UnwrapResolvables<T> = {
413
[K in keyof T]: T[K] extends ResolvableTo<infer R> ? R : T[K]
514
}
615

7-
type ResolvedConfig<T extends Config> = Omit<T, 'theme'> & {
8-
theme: UnwrapResolvables<T['theme']>
16+
type ThemeConfigResolved = UnwrapResolvables<ThemeConfig>
17+
type DefaultThemeFull = DefaultTheme & { colors: DefaultColors }
18+
19+
type MergeThemes<Overrides extends object, Extensions extends object> = {
20+
[K in keyof ThemeConfigResolved | keyof Overrides]: (K extends keyof Overrides
21+
? Overrides[K]
22+
: K extends keyof DefaultThemeFull
23+
? DefaultThemeFull[K]
24+
: K extends keyof ThemeConfigResolved
25+
? ThemeConfigResolved[K]
26+
: never) &
27+
(K extends keyof Extensions ? Extensions[K] : {})
928
}
1029

1130
declare function resolveConfig<T extends Config>(config: T): ResolvedConfig<T>

scripts/generate-types.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ fs.writeFileSync(
9191
path.join(process.cwd(), 'types', 'generated', 'default-theme.d.ts'),
9292
prettier.format(
9393
`
94-
import { Config } from '../../types'
9594
type CSSDeclarationList = Record<string, string>
96-
export type DefaultTheme = Config['theme'] & { ${defaultThemeTypes} }
95+
export type DefaultTheme = { ${defaultThemeTypes} }
9796
`,
9897
{
9998
semi: false,

types/config.d.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ type Screen = { raw: string } | { min: string } | { max: string } | { min: strin
8080
type ScreensConfig = string[] | KeyValuePair<string, string | Screen | Screen[]>
8181

8282
// Theme related config
83-
interface ThemeConfig {
83+
export interface ThemeConfig {
8484
// Responsiveness
8585
screens: ResolvableTo<ScreensConfig>
8686
supports: ResolvableTo<Record<string, string>>
@@ -235,8 +235,9 @@ interface ThemeConfig {
235235
transitionDuration: ResolvableTo<KeyValuePair>
236236
willChange: ResolvableTo<KeyValuePair>
237237
content: ResolvableTo<KeyValuePair>
238+
}
238239

239-
// Custom
240+
interface CustomThemeConfig extends ThemeConfig {
240241
[key: string]: any
241242
}
242243

@@ -361,7 +362,7 @@ interface OptionalConfig {
361362
future: Partial<FutureConfig>
362363
experimental: Partial<ExperimentalConfig>
363364
darkMode: Partial<DarkModeConfig>
364-
theme: Partial<ThemeConfig & { extend: Partial<ThemeConfig> }>
365+
theme: Partial<CustomThemeConfig & { extend: Partial<CustomThemeConfig> }>
365366
corePlugins: Partial<CorePluginsConfig>
366367
plugins: Partial<PluginsConfig>
367368
// Custom

0 commit comments

Comments
 (0)