Skip to content

astro-jsx.d.ts references KebabKeys, which dist/type-utils does not export (TS2694) #17727

Description

@nerymurillohnd

Astro Info

Astro                    v7.2.2
Vite                     v8.2.1
Node                     v24.19.0
System                   macOS (arm64)
Package Manager          npm
Output                   server
Adapter                  @astrojs/cloudflare (v14.2.1)
Integrations             @astrojs/svelte (v9.0.1)
                         astro-favicons (v3.1.6)

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

packages/astro/astro-jsx.d.ts:509 imports a type that type-utils does not export:

type KebabCSSDOMProperties = import('./dist/type-utils.js').KebabKeys<DOMCSSProperties>;

src/type-utils.ts (and the published dist/type-utils.d.ts) export exactly seven types, none of them KebabKeys:

Simplify, WithRequired, OmitIndexSignature, OmitPreservingIndexSignature, ValueOf, MapValue, DeepPartial

The line immediately below it uses Simplify from the same module and resolves fine, so this is not a module-resolution problem — the type simply does not exist. A code search across withastro/astro returns one occurrence of KebabKeys in the whole repository: the consumer above. There is no definition, so this is present on main and not only in the published tarball. It looks like the type was removed or renamed and this reference was left behind.

How to surface it

It is readable in the published package, but to see it in a compile, opt out of skipLibCheck:

// tsconfig.json
{
  "extends": "astro/tsconfigs/strictest",
  "compilerOptions": { "skipLibCheck": false }
}
$ npx tsc --noEmit
node_modules/astro/astro-jsx.d.ts(509,62): error TS2694: Namespace '.../node_modules/astro/dist/type-utils' has no exported member 'KebabKeys'.

It also appears in-editor with no config change at all, because opening astro-jsx.d.ts types it in an inferred project where skipLibCheck does not apply. That is how I ran into it.

Why this has probably stayed invisible

astro/tsconfigs/base.json:25 sets skipLibCheck: true, and both strict.json and strictest.json extend it. Every project on a shipped preset therefore suppresses this error, and it only surfaces if someone opts out or opens the file directly. I could not find an existing issue for it anywhere on GitHub.

Impact — deliberately stated as small

I do not think this breaks anyone's build, and I would rather say so than overstate it. StyleObject is:

type StyleObject = Simplify<KebabCSSDOMProperties & DOMCSSProperties & AllCSSProperties>;

and AllCSSProperties is an index signature accepting any string key, so CSSProperties still accepts everything regardless of what KebabCSSDOMProperties resolves to. The practical loss is autocomplete for kebab-case CSS properties in style={{ … }} objects, plus an erroneous type sitting in the public .d.ts surface that anyone disabling skipLibCheck will hit.

What's the expected result?

astro-jsx.d.ts should reference a type that exists, so that the public .d.ts surface type-checks on its own.

Either:

  1. Restore KebabKeys in src/type-utils.ts (if the kebab-case key mapping was meant to stay), or
  2. Drop the reference and let DOMCSSProperties and AllCSSProperties carry StyleObject on their own.

Option 2 is the smaller change and, as far as I can tell, changes nothing observable — AllCSSProperties already accepts any string key. Option 1 is the one that restores kebab-case autocomplete, if that was the intent.

Link to Minimal Reproducible Example

type KebabCSSDOMProperties = import('./dist/type-utils.js').KebabKeys<DOMCSSProperties>;

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)pkg: astroRelated to the core `astro` package (scope)triage: fix pendingReporter needs to verify the triage bot fix works

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions