Skip to content

Conversation

@KazimirPodolski
Copy link
Contributor

πŸ”— Linked issue

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Quickfix IconProps type so that Vue won't overload the console with complains when Icon gets a functional component (e.g. from Lucide):

[Vue warn]: Invalid prop: type check failed for prop "icon". Expected String | Object, got Function  
  at <Button icon=fn variant="subtle" color="primary"  ... > 
  ...

Tested locally, the warning is gone now.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 20, 2025

npm i https://pkg.pr.new/@nuxt/ui@5498

commit: 3dc5ab9

@benjamincanac
Copy link
Member

Do you have an example of the object you're passing so I can try? The Component type is quite big and overloads the component meta in the docs so I have to tweak this.

@benjamincanac benjamincanac changed the title fix(types): fix IconProps' name type fix(Icon): improve name type Nov 20, 2025
@KazimirPodolski
Copy link
Contributor Author

E.g. something like this:

<script setup lang="ts">
import { LucideArchive } from 'lucide-vue-next';
</script>

<template>
  <UButton :icon="LucideArchive"/>
</template>

Anything really imported from 'lucide-vue-next' and passed down to Icon one way or the other.

@KazimirPodolski
Copy link
Contributor Author

Maybe just adding | Function is the easier tweak then?

Comment on lines 2 to +3
export interface IconProps {
name: string | object
name: string | any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export interface IconProps {
name: string | object
name: string | any
import type { Component } from 'vue'
export interface IconProps {
name: string | Component

The type definition uses any instead of properly supporting functional components, which disables TypeScript type checking and doesn't match the PR description that states it should "accept Function".

View Details

Analysis

Icon component type definition loses TypeScript type safety

What fails: IconProps.name type definition uses string | any instead of string | Component, which disables TypeScript type checking and allows invalid values like numbers and booleans to be passed without errors.

How to reproduce:

import type { Component } from 'vue'

// Current broken implementation (string | any)
interface BrokenIconProps {
  name: string | any
}

// This incorrectly passes type checking:
const badProps: BrokenIconProps = { name: 123 }      // Should error
const badProps2: BrokenIconProps = { name: true }    // Should error

// Fixed implementation (string | Component)
interface FixedIconProps {
  name: string | Component
}

// These correctly fail type checking:
// @ts-expect-error
const goodProps: FixedIconProps = { name: 123 }      // Error: Type 'number' not assignable

Result with current any type: TypeScript allows any value to be assigned to name without warnings, including 123, true, or other invalid values.

Expected behavior: TypeScript should reject non-component values. Using string | Component (from Vue's official type exports) provides proper type safety for component definitions.

Note: The component logic at lines 25-26 correctly handles both strings and components at runtime with typeof name === 'string' checks, but TypeScript type safety was removed when the prop type was changed from string | Component (commit 96dbce7) to string | any (commit 3dc5ab9). This fix restores proper type checking while maintaining backward compatibility with the existing runtime behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll put back Component when possible!

@benjamincanac benjamincanac merged commit b654a77 into nuxt:v4 Nov 21, 2025
16 checks passed
@KazimirPodolski KazimirPodolski deleted the fix-iconprops-type branch November 21, 2025 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants