Fix TS2742 error when inferring exported Config type (#19707)
Type aliases get resolved through to `UserConfig` during declaration emit, which lives in a hashed internal DTS chunk with no stable import path, causing TS2742. This is 100% backwards-compatible because type aliases and interfaces are structurally comparable. Fixes: https://github.com/tailwindlabs/tailwindcss/issues/15844 Fixes: https://github.com/tailwindlabs/tailwindcss/issues/19706 Fixes: https://github.com/tailwindlabs/tailwindcss/discussions/15458 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This commit is contained in:
parent
f036f80195
commit
6cf1af26b3
5 changed files with 156 additions and 2 deletions
|
|
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Canonicalization: migrate arbitrary `:has()` variants from `[&:has(…)]` to `has-[…]` ([#19991](https://github.com/tailwindlabs/tailwindcss/pull/19991))
|
||||
- Upgrade: don’t migrate inline `style` attributes ([#19918](https://github.com/tailwindlabs/tailwindcss/pull/19918))
|
||||
- Allow multiple `@utility` definitions with the same name but different value types ([#19777](https://github.com/tailwindlabs/tailwindcss/pull/19777))
|
||||
- Export missing `PluginWithConfig` type from `tailwindcss/plugin` to fix errors when inferring plugin config types ([#19707](https://github.com/tailwindlabs/tailwindcss/pull/19707))
|
||||
|
||||
## [4.2.4] - 2026-04-21
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,72 @@ test(
|
|||
},
|
||||
)
|
||||
|
||||
// https://github.com/tailwindlabs/tailwindcss/issues/19706
|
||||
test(
|
||||
'Config files (TS, valid types)',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"tailwindcss": "workspace:^",
|
||||
"@tailwindcss/cli": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'tsconfig.json': json`
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"declaration": true,
|
||||
"composite": true,
|
||||
"outDir": "./.build",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["tailwind.config.ts"]
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
<div class="text-primary"></div>
|
||||
`,
|
||||
'tailwind.config.ts': ts`
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
function defineConfig(config: Config): Config {
|
||||
return config
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'blue',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
`,
|
||||
'src/index.css': css`
|
||||
@import 'tailwindcss';
|
||||
@config '../tailwind.config.ts';
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ fs, exec }) => {
|
||||
// We expect that these commands don't crash:
|
||||
await exec('pnpm tsc -b')
|
||||
await exec('pnpm tailwindcss --input src/index.css --output dist/out.css')
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [candidate`text-primary`])
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (CJS, watch mode)',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { candidate, css, html, json, test } from '../utils'
|
||||
import { candidate, css, html, json, test, ts } from '../utils'
|
||||
|
||||
test(
|
||||
'builds the `@tailwindcss/typography` plugin utilities',
|
||||
|
|
@ -207,3 +207,88 @@ test(
|
|||
])
|
||||
},
|
||||
)
|
||||
|
||||
// https://github.com/tailwindlabs/tailwindcss/issues/15844
|
||||
test(
|
||||
'builds CSS with a custom plugin compiled from TypeScript',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"tailwindcss": "workspace:^",
|
||||
"@tailwindcss/cli": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'tsconfig.json': json`
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"declaration": true,
|
||||
"composite": true,
|
||||
"rootDir": "./src",
|
||||
"outDir": "./.build",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
<div class="test-red"></div>
|
||||
`,
|
||||
'src/index.css': css`
|
||||
@import 'tailwindcss';
|
||||
@plugin '../.build/plugin.js';
|
||||
`,
|
||||
'src/plugin.ts': ts`
|
||||
import plugin from 'tailwindcss/plugin'
|
||||
|
||||
export const typedPlugin = plugin(() => {
|
||||
return ({ matchComponents }) => {
|
||||
matchComponents(
|
||||
{
|
||||
test: (content: string) => ({
|
||||
color: content,
|
||||
}),
|
||||
},
|
||||
{
|
||||
values: {
|
||||
red: 'red',
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default plugin(({ matchComponents }) => {
|
||||
matchComponents(
|
||||
{
|
||||
test: (content: string) => ({
|
||||
color: content,
|
||||
}),
|
||||
},
|
||||
{
|
||||
values: {
|
||||
red: 'red',
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ fs, exec }) => {
|
||||
// We expect that these commands don't crash:
|
||||
await exec('pnpm tsc -b')
|
||||
await exec('pnpm tailwindcss --input src/index.css --output dist/out.css')
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [candidate`test-red`])
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ import { segment } from './utils/segment'
|
|||
import { topologicalSort } from './utils/topological-sort'
|
||||
import { compoundsForSelectors, IS_VALID_VARIANT_NAME, substituteAtVariant } from './variants'
|
||||
import { walk, WalkAction } from './walk'
|
||||
export type Config = UserConfig
|
||||
|
||||
export interface Config extends UserConfig {}
|
||||
|
||||
const IS_VALID_PREFIX = /^[a-z]+$/
|
||||
|
||||
|
|
|
|||
|
|
@ -41,5 +41,6 @@ export type {
|
|||
PluginFn as PluginCreator,
|
||||
Plugin as PluginsConfig,
|
||||
PluginUtils,
|
||||
PluginWithConfig,
|
||||
ThemeConfig,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue