Skip to content

🐛 False Unused exported enum members #989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
6 tasks done
liza-s-orchid opened this issue Mar 18, 2025 · 2 comments
Open
6 tasks done

🐛 False Unused exported enum members #989

liza-s-orchid opened this issue Mar 18, 2025 · 2 comments
Labels
bug Something isn't working

Comments

@liza-s-orchid
Copy link

liza-s-orchid commented Mar 18, 2025

Prerequisites

Reproduction url

https://github.com/liza-s-orchid/knip-bug

Reproduction access

  • I've made sure the reproduction is publicly accessible

Description of the issue

In this scenario, there is an enum with initializers:

export enum Color {
    Red = 1,
    Green = 2,
    Blue = 3
}

That enum is imported and used in a zod schema:

const schema = z.object({
    color: z.nativeEnum(Color)
})

With this code, Knip reports each enum member as unused, but effectively, every enumerated value is used in the context of the type definition.

I encountered a similar issue in the following topics (which were resolved):
#699
#703

@liza-s-orchid liza-s-orchid added the bug Something isn't working label Mar 18, 2025
@webpro
Copy link
Member

webpro commented Mar 18, 2025

Thanks for the report and reproduction.

Fixing and supporting this would make the implementation even easier: if the enum is an argument of any call expression (not just some Object.* methods) we could consider all members used. However, the issue is that there's also methods we know should not mark all members as referenced, such as Object.is or any function we don't know the implementation of.

Unfortunately, the type-checker doesn't find references through e.g. z.nativeEnum either (i.e. similar to "Find All References" in an IDE like VS Code). So, there's three options I guess:

  1. consider members referenced if enum is argument in any call expression → we'd miss out on enum members, OR
  2. maintain a list of methods (e.g. Object.keys etc) → even we'd start tracking external methods such as z. nativeEnum then we'd need to make sure z is actually zod (could be imported as any name?), OR
  3. do nothing (i.e. maintain a "safer" list of language built-ins), do nothing, and allow users to ignore, eg:
export enum Color {
    Red = 1,
    /** @lintignore */
    Green = 2,
    Blue = 3
}
knip --tags=-lintignore

..or..

{
  "tags": ["-lintignore"]
}

I'm leaning towards the third option, as at this point I think it should lead to best results. Even though it's potentially a hassle to deal with, it's better than ignorance/blind spots.

@Palid
Copy link

Palid commented Apr 11, 2025

@webpro I got another usecase: when you're using const enum you sometimes need to export it so it properly enumerates on tsc compilation, even though it's technically not being imported anywhere.
Moving it to separate file solves the problem, so it probably can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants