-
Notifications
You must be signed in to change notification settings - Fork 22
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
feat(zipObj): stricter types, add test #88
Conversation
While I understand what you're changes do, I'm struggling to find the use case for it. What you're additions are handling for tuples, but not only tuples, strict subtypes within (eg Was hoping you could provide some |
To dive into specifically when I mean here... all your unit tests utilize tuples in that each index of the array is strongly typed to be separate: zipObj(['bool', 'number', 'null', 'undefined'], [true, 1, null, undefined]) This use case is extremely rare. Even you did receive back from an API this way, as a list of key/value tuples type Types = {
'bool': boolean;
'number': number;
'null': null;
'undefined': undefined;
};
type Person = {
'name': string;
'age: number;
'gender': 'M' | 'F' | 'X';
}; My concern over this additional typing is the complexity of it. And while yes we could do it this way, doesn't mean we actually should. And in this case, I think the complexity of extracting an exact type over exactly defined tuples is not worth it. Type casting does the trick just the same since you can define the exact type of the object ahead of time as well const person = zipObj(['bool', 'number', 'null', 'undefined'], [true, 1, null, undefined]) as Person; // gives you what you'd need 99% of the time I'm making some assumptions here of course, as I don't know your actually use course, and I'm more than happen to entertain it and discuss. But right now my gut is telling me that adding the additional complexity is not worth support a <1% edge case of usage |
While I agree with your concern, my use case was based on // Might be slightly wrong, but you got the idea
const splitBools = pipe(
partition((v):v is boolean => typeof v === 'boolean'),
zipObj(['bools', 'others'])
)
const splitted = splitBools(['a', 1, true])
type Expected = {bools: boolean[], other: Array<number | string>}
type Actual = {
bools: boolean[] | (string | number)[];
others: boolean[] | (string | number)[];
} Also, narrowing 2nd parameter as tuple when possible won't actually narrow to literals most of the times, since the 2nd param will be wider at usage. |
Hello, do you need anything for this PR ? Or should I close it ? |
Please keep it open. I've been meaning to come back to it to review. I wanted to get your other MR as well as mine for |
I also have a much better idea why you wanted this changes and how the complexity helps from those other MRs. So I'm not still apposed to these changes as I initially called out as a concern. Now it's just a point to review the changes themselves. I'll try to block out some time before the end of this week to do that |
There's no rush, I'm a FOSS maintainer too, I know what it is. I just wanted to be sure this PR has a chance to be useful |
types/zipObj.d.ts
Outdated
|
||
export type _ZipObj<K extends readonly PropertyKey[], V extends {[key in keyof K]: unknown} | readonly unknown[]> = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This utility type cannot live in this file. The build script combines all the files into one and copies the ramda
block comments over. It forces us to have one export function per file
Don't add it to src/types/util/tools.d.ts
though. I want to break that file up into a bunch of smaller ones (who has the time, right?)
Instead, do it like I have src/types/util/deepModify.d.ts
by creating a new file src/types/util/zipObj.d.ts
.
I made a key assumption about the complexity of the typings in that it would return something like this: const r = zipObj(['foo', 'bar'], [1, 2]);
// ^? _.L.ZipObj<['foo', bar'], [1, 2]> Those types coming out of a library that can take plan array/object types in and not return them back out is not a goot user experience and is something I'm trying to avoid where I can. To my present surprise, it actually returns plan types! const r = zipObj(['foo', 'bar'], [1, 2]);
// ^? { foo: 1, bar: 2 } I tested your changes against the existing tests defined in DefinitelyTyped and all passed |
Just as a note, if you need a hand for some type definitions, and since I love TS types, don't hesitate to ping me somehow, maybe by creating an issue. |
Hey there, hope you're doing well ! Would it be possible to have this merged soon ? |
Narrow values types per key when possible, otherwise fallback on wider mapped type.
Tests included