Open craigkovatch opened 6 years ago
Interesting regarding the indirect imports. I wonder if there is a clean way to just change something in the definitions file so only direct imports are affected. I’ll have a think about this, but I’m not opposed to moving to DefinitelyTyped if there is no viable alternative. (Though one wonders if that would really solve the problem — if I import a package that depends on @types/colors, wouldn’t my String also get polluted?) Some examples to play with would probably be useful here...
@types/*
dependencies are devDependencies
, so they aren't pulled into the published package artifact. In this case you're publishing your typing file along with your library, which to my knowledge isn't bad practice per se, but when combined with the global extension of String
leads to this pollution. In other words, a package which depends on @types/colors
would not pull @types/colors
along for the ride, it would only use it for its own local build. Including it in your main package is the source of the pain.
My understanding of this package is that the extension of String.prototype is considered one of the primary features. If that's the case, moving back into DefinitelyTyped, or at least a separate package for just your index.d.ts file, is the only solution that I can see.
How about custom theme?
You might need to add
interface String {
strip: string;
[key: string]: string;
}
@kamontat that would completely remove all member type safety from the global String
interface.
Hey @craigkovatch sorry for delayed reply. The thing I want to clarify is -- is the current behavior correct? For example, .cyan
popus up in autocomplete, but does that actually work? In other words, are the autocomplete suggestions misleading/incorrect, or are they correct but just annoying? If it's the latter, have you tried a vanilla Node-style import of colors, e.g. const colors=require('colors')
(which I think ignores typings), instead of e.g. import * from 'colors'
(which I think will pull in the typings)? Let me know what you think!
My package doesn't use colors
, that's the problem :) My package consumes a package which consumes a package which consumes colors
, but because these typings are written against the global String
interface I have no ability to "mute" them.
Your typings are correct AFAIK, but I've never actually used your package :) From the documentation I've read, if the package deep in my tree used colors/safe
rather than colors
, I wouldn't have this issue. But I don't have control over that, and fixing it by forcing the typings to be an intentional, build-time inclusion is the only way I can see to fix it in one place rather than hoping hundreds of other people get it right. LMK if you think I'm missing something, though.
For now I've fixed this in my package by overriding to colors 1.1.2, i.e. the last release before 08ce915. But that's...less than ideal.
Fair enough -- sigh :) Will work on getting the typings back into DT for the next release.
It would probably be worth asking someone on that side if they have other ideas. I'm not claiming to be the world's expert or anything :) I think what you're doing here is indeed the recommendation by Microsoft for TypeScript, but this package is an extreme edge case in that colors
wants both to extend String.prototype
and it's a low-level util library, so likely to be deep in the dependency tree. That's why I think @types/colors is the right-and-only choice here. But if there is another way, I'd be happy to learn it!
Agreed -- the best practice is indeed to include typings in the repo whenever possible for TS, but most packages don't extend JS prototypes. And while it's correct still, it's definitely annoying if you're building an app that has nothing to do with colors but still sees all those extra typings (if it weren't in the global namespace, like most packages, you wouldn't see the typings). So, I think this is a valuable discussion! A lot of this is an art not a science... :)
I'm not really using TypeScript myself so I'm not able to offer a good solution for this.
Is there anyway we can programmatically switch the TypeScript imports based on whether or not the String.prototype
code is loaded?
I agree with @craigkovatch in that having all these overloaded string methods popup unexpectedly in VS Code is not ideal, but it is to my understanding that in his case String is actually being overloaded, so the TS definitions that appear are correct?
Generally I'd like to go for the least surprising behavior for all users. If you've depended on a package that does require('colors')
and not require('colors/safe')
, it probably shouldn't be surprising if the Types are loaded on String as well.
No reply needed for me. Hope this helps. Let me know if you need help making a decision @DABH
Good point! I will investigate and get back.
@Marak @DABH no, it would not appear that String is overloaded at runtime. This issue is just about pollution of typings.
I see this has been an issue for a very long time; is there any plan to fix it? Maybe I can help with that if we come up with an idea of how to do so
The typings for this library are polluting the global String interface. In every package which consumes (directly or indirectly) this package, every
String
is getting a bunch of extra noise in the autocomplete results.If it's relevant this is VS Code 1.27.2, TypeScript 2.8.3.
I believe this was caused by this commit in February 2018: 08ce9159f4f2af07f4c631ba10fbecc16190b00a
Specifically, pulling the typings into your library in this way means that they are exposed to indirect consumers, rather than explicitly pulled in by direct consumers via the @types packaging. I suggest returning to the previous method, e.g. via DefinitelyTyped.