Skip to content

fix: update types#481

Open
gameroman wants to merge 1 commit intoes-tooling:mainfrom
gameroman:replacement.description
Open

fix: update types#481
gameroman wants to merge 1 commit intoes-tooling:mainfrom
gameroman:replacement.description

Conversation

@gameroman
Copy link
Copy Markdown
Contributor

@gameroman gameroman commented Mar 26, 2026

🔗 Linked issue

📚 Description

Add description?: never to DocumentedModuleReplacement for easier use with typescript

This is to avoid doing things like this:

https://github.com/npmx-dev/npmx.dev/blob/d80c709c30b41ac68bb91b6524fabe59477417d2/app/components/Package/Replacement.vue#L17-L19

@gameroman gameroman changed the title add description?: never to DocumentedModuleReplacement for easier… chore: update types Mar 26, 2026
@gameroman gameroman marked this pull request as ready for review March 26, 2026 17:58
@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 26, 2026

I'm not sure this is right. Documented replacements can have their own URL. They just don't right now.

But it was typed this way because some may need their own one day that isn't the same as the mapping URL.

Don't have an example off the top of my head though

@gameroman
Copy link
Copy Markdown
Contributor Author

This is description, not URL

@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 27, 2026

Sorry it also applies to the description 😅

It is possible we want a description on any given replacement. We just happen to not have any right now on documented ones.

If we remove this, we're locking ourselves out of the option in future without a breaking change

@gameroman
Copy link
Copy Markdown
Contributor Author

In that case we can add description?: string to ModuleReplacementLike instead

@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 27, 2026

Actually now that I've looked properly, I'm a bit lost 😅

Documented replacements already don't have descriptions. So the types are already right, no?

@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 27, 2026

this was by design though since all consumers should be narrowing the tagged union really.

having description: never doesn't feel right since the type shouldn't have the property at all.

@gameroman
Copy link
Copy Markdown
Contributor Author

description?: never is just saying that description is always undefined but allows you to use description property in union contexts

@gameroman
Copy link
Copy Markdown
Contributor Author

And the difference between description?: never and description: undefinedis thatdescription?: nevershows thatdescription` does not actually exists as a property on an object

@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 27, 2026

i understand what it does - but it declares that the type has a property description which isn't true.

the value is never.

i know this seems picky but i really believe this is just a workaround to avoid having to narrow the types properly. the current types are correct imo

@gameroman
Copy link
Copy Markdown
Contributor Author

@bluwy @ghostdevv what do you think?

@joaopedrodcf
Copy link
Copy Markdown
Contributor

having a type never seems quite strange to me you did ?? "" because it can be undefined no ?

image

@gameroman
Copy link
Copy Markdown
Contributor Author

Yes, description can be undefined on ModuleReplacement, but because DocumentedModuleReplacement does not have the description property at all typescript will complain that

Property 'description' does not exist on type 'DocumentedModuleReplacement'

By adding description?: never we are allowing us to access description on ModuleReplacement

Also I want to note that description?: never and description?: undefined are exactly the same thing

@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 27, 2026

we're not comparing never and undefined though.

// this
interface X {
  prop?: never;
}

// is not the same as this
interface X {
  // no prop at all
}

the types are correct right now and are doing their job by making you narrow the union correctly.

it may feel like a pain but the documented replacements don't have a description property at all. setting them to never is just a workaround to avoid having to narrow the type.

@gameroman
Copy link
Copy Markdown
Contributor Author

But why would you want to narrow the type for the description that is already optional on other types?

@43081j
Copy link
Copy Markdown
Contributor

43081j commented Mar 28, 2026

Because documented replacements don't have a description. It isn't optional, they just don't have one at all.

So you correctly have to narrow the type to ones which do have a description.

This is just a workaround to avoid having to do the narrowing

@gameroman gameroman changed the title chore: update types fix: update types Mar 28, 2026
@gameroman
Copy link
Copy Markdown
Contributor Author

gameroman commented Mar 28, 2026

I would say this is actually a very common way to do this when dealing with type unions, for example

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/083439f50a07de259eb9690cb0a3d8121f7c60bc/types/npmcli__arborist/index.d.ts#L441-L461

playground

@gameroman
Copy link
Copy Markdown
Contributor Author

What would be yours proposed solution?

@gameroman
Copy link
Copy Markdown
Contributor Author

I’m JavaScript it doesn’t matter if property is undefined or it doesn’t exist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants