#4050·tamagui

v5 config + `declare module`: long-form style props lose type-safety ('Property marginTop does not exist'); shorthands are the trigger

Author: leogouveiaCreated Jun 25, 2026Updated Jun 25, 2026

Current Behavior

With @tamagui/config/v5 defaultConfig and the documented declare module "tamagui" config augmentation, a subset of long-form style props loses type-safety on Text/YStack/View. TypeScript reports Property 'marginTop' does not exist…, Property 'textAlign' does not exist…, Property 'alignItems' does not exist…, etc., even though the props work fine at runtime.

The failing set is inconsistent but deterministic — e.g. width type-checks but w doesn't; mt type-checks but marginTop doesn't; color/fontSize work but marginTop/textAlign/alignItems/padding/backgroundColor don't. This is the signature of TypeScript hitting an internal limit while resolving an oversized intersection type and silently dropping properties.

This looks closely related to the (closed) #3585 and #3285, but still reproduces on the latest 2.x line.

Expected Behavior

All valid style props (long-form and shorthand) are type-checked correctly when the config is augmented via declare module.

Tamagui Version

tamagui: 2.3.3
@tamagui/config: 2.3.3
@tamagui/web: 2.3.0

Platform (Web, iOS, Android)

All platforms — this is purely type-level (tsc), independent of runtime/bundler.

Reproduction

Minimal, type-level only. No bundler needed — npx tsc --noEmit is enough.

tamagui.config.ts (exactly as documented):

typescript
import { defaultConfig } from "@tamagui/config/v5";
import { createTamagui } from "tamagui";

export const tamaguiConfig = createTamagui(defaultConfig);
export default tamaguiConfig;

export type AppTamaguiConfig = typeof tamaguiConfig;
declare module "tamagui" {
  interface TamaguiCustomConfig extends AppTamaguiConfig {}
}

probe.tsx:

typescript
import { Text, YStack } from "tamagui";

export function Probe() {
  return (
    <YStack alignItems="center" marginTop="$8" padding="$4">
      <Text color="$gray10" textAlign="center" fontSize="$5">ok</Text>
    </YStack>
  );
}

Run: npx tsc --noEmit

Result: errors such as

error TS2322: Property 'marginTop' does not exist on type 'IntrinsicAttributes & Omit<RNTamaguiTextNonStyleProps, keyof TextStylePropsBase | "unstyled"> & ...5 more... & RefAttributes<...>'.
error TS2322: Property 'textAlign' does not exist ...
error TS2322: Property 'alignItems' does not exist ...

…while color and fontSize on the same element produce no error.

Investigation / findings

I bisected the config to isolate the trigger (all on the repro above, tsc --noEmit):

Config Long-form style props
defaultConfig (as documented) ❌ truncated
reduce media 31 → 3 keys ❌ (truncation boundary just shifts)
media: {} only ❌ still fails
shorthands: {} (default 31 media kept) ✅ all long-form props type-check
shorthands: {} + media: {}

The dominant trigger is the shorthands set, not media. With shorthands: {}, every long-form prop (incl. theme tokens like marginTop="$8") type-checks correctly, even with all 31 default media keys.

Root cause appears to be the combinatorial intersection in WithThemeShorthandsPseudosMedia (@tamagui/web/types/types.d.ts): WithThemeValues & WithShorthands & WithPseudoProps<all> & WithMediaProps<all> — 33 shorthands × 8 pseudos × 31 media keys, each level re-spreading the full style set (with Partial<CSSProperties> nested under media). The resulting intersection exceeds TypeScript's property-resolution limits.

Also confirmed:

  • Not a TS 6.0 regression — TypeScript 5.9.2 produces the identical set of errors.
  • Runtime is unaffected; this is type-only.

Workaround: createTamagui({ ...defaultConfig, shorthands: {} }) restores full type-safety for long-form props (at the cost of the shorthand aliases). This is consistent with the changelog note that onlyAllowShorthands "had been breaking in many configurations" — the shorthand surface is the lever.

System Info

System:
  OS: Windows 11 10.0.26200
  CPU: (32) x64 AMD Ryzen 9 7950X 16-Core
Binaries:
  Node: 24.16.0
  pnpm: 11.3.0
npmPackages:
  @tamagui/config: 2.3.3
  tamagui: 2.3.3
  expo: 56.0.12
  react: 19.2.3
  react-native: 0.85.3
  typescript: 6.0.3 (also reproduced on 5.9.2)