lodash: replace StringRepresentable with more specific types#20717
lodash: replace StringRepresentable with more specific types#20717sheetalkamat merged 1 commit intoDefinitelyTyped:masterfrom
Conversation
|
types/lodash/index.d.ts to authors (@bczengel @chrootsu @stepancar @ericanderson @aj-r @Ailrun @e-cloud). Could you review this PR? |
|
@thorn0 Please fix the failures indicated in the Travis CI log. |
|
A lot of things have changed in the code because of #19356. I'll need some time to redo this PR. |
69f37ca to
491aff4
Compare
|
@thorn0 - It appears Travis did not correctly run on this PR! /cc @RyanCavanaugh to investigate and advise. |
491aff4 to
85aae8f
Compare
85aae8f to
9fd9983
Compare
83b6be7 to
e2e4fa8
Compare
e2e4fa8 to
4ae1ec8
Compare
|
@RyanCavanaugh any idea what's up with this Travis error? It seems to happen only when testing with TS 2.3:
For reference: https://travis-ci.org/DefinitelyTyped/DefinitelyTyped/builds/290799350#L3375 |
4ae1ec8 to
3644f54
Compare
|
Seems like I've fixed it. Now Travis shows only the |
aj-r
left a comment
There was a problem hiding this comment.
You might want to disable the no-redundant-jsdoc option in tslint.json, based on the Travis errors.
types/lodash/index.d.ts
Outdated
| */ | ||
| fromPairs<T>( | ||
| array: List<[StringRepresentable, T]> | null | undefined | ||
| array?: List<[PropertyName, T]> | null | undefined |
There was a problem hiding this comment.
According to the documentation, array is not optional.
There was a problem hiding this comment.
As per the same documentation, it also can't be null nor undefined. Shall we remove them?
There was a problem hiding this comment.
I created an issue a while ago (#15883) to add the null | undefined options to most functions that do non-mutating array operations. While it's not explicitly documented, lodash does handle null and undefined values gracefully. The reason being is that this saves you from needing to do a null check before calling these functions.
For example, if you have something like this:
function process(pairs?: List<[string, number]>) {
const obj = _.fromPairs(pairs);
...
}
then you don't need to check if pairs is undefined - you can just use it. Lodash doesn't require people to do that check, so we shouldn't either. But I think we should at least require people to pass in an argument. _.fromPairs() is almost certainly a mistake, since it will always return {}, So it would be better for the programmer to just write {} instead of _.fromPairs().
| * @see _.zipObjectDeep | ||
| */ | ||
| zipObjectDeep(): {}; | ||
| ): object; |
There was a problem hiding this comment.
I don't like returning object because it's not assignable to pretty much anything. For example, this code will break:
interface Person {
name: string;
age: number;
}
const p: Person = _.zipObjectDeep(["name", "age"], ["Joe", 32]);
I would prefer to return any in the general case, and only return object if no arguments were provided.
There was a problem hiding this comment.
In general, type assertions should be explicit. So instead of
const p: Person = _.zipObjectDeep(["name", "age"], ["Joe", 32]);it's better to write
const p = _.zipObjectDeep(["name", "age"], ["Joe", 32]) as Person;There was a problem hiding this comment.
@aj-r Do you insist on using any? If so I'll change it, but I don't feel like it's the right choice.
There was a problem hiding this comment.
According to the common mistakes, it looks like you are right - we should be forcing people to use a type assertion. So I guess object is ok.
| this: LoDashImplicitWrapper<List<PropertyPath>>, | ||
| values?: List<any> | ||
| ): LoDashImplicitWrapper<TResult>; | ||
| ): LoDashImplicitWrapper<object>; |
There was a problem hiding this comment.
Better to return any than object
| this: LoDashExplicitWrapper<List<StringRepresentable>|List<List<any>>>, | ||
| values?: List<any> | ||
| ): LoDashExplicitWrapper<TResult>; | ||
| ): LoDashExplicitWrapper<object>; |
There was a problem hiding this comment.
Better to return any than object.
| * @see _.zipObjectDeep | ||
| */ | ||
| zipObjectDeep(): {}; | ||
| ): object; |
There was a problem hiding this comment.
According to the common mistakes, it looks like you are right - we should be forcing people to use a type assertion. So I guess object is ok.
types/lodash/index.d.ts
Outdated
| */ | ||
| fromPairs<T>( | ||
| array: List<[StringRepresentable, T]> | null | undefined | ||
| array?: List<[PropertyName, T]> | null | undefined |
There was a problem hiding this comment.
I created an issue a while ago (#15883) to add the null | undefined options to most functions that do non-mutating array operations. While it's not explicitly documented, lodash does handle null and undefined values gracefully. The reason being is that this saves you from needing to do a null check before calling these functions.
For example, if you have something like this:
function process(pairs?: List<[string, number]>) {
const obj = _.fromPairs(pairs);
...
}
then you don't need to check if pairs is undefined - you can just use it. Lodash doesn't require people to do that check, so we shouldn't either. But I think we should at least require people to pass in an argument. _.fromPairs() is almost certainly a mistake, since it will always return {}, So it would be better for the programmer to just write {} instead of _.fromPairs().
6421cd3 to
e5fdde8
Compare
|
@aj-r Travis is green finally. Please have a look. |
e5fdde8 to
42fe570
Compare
|
@aj-r - Thanks for your review of this PR! Can you please look at the new code and update your review status if appropriate? |
|
Approved by a listed owner. PR ready to merge pending express review by a maintainer. |
This interface is used in many places throughout the type definitions, but I believe it's a mistake because almost any type (even
{}) can be assigned to it fortoStringis a member of theObjectinterface. Effectively,StringRepresentableis an alias for{}.No errors. playground
Why lose type checking for the sake of some rare use cases that can be fixed with an explicit
.toString()call? For reference, look atlib.d.tsand functions likeparseIntthere. Also see microsoft/TypeScript#15368 where @RyanCavanaugh wrote:There must exist other issues discussing this. It's simply the first one that I found.
StringRepresentableis chiefly used for property names, for which it's totally common to use numbers, so I replaced it withstring | numberwhere it made sense.