-
-
Notifications
You must be signed in to change notification settings - Fork 147
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
O.P.Pick from arrays #57
Comments
I don't mind having breaking changes when it comes to keeping up with ts. These are advanced types, so it makes sense that versions will break. However, I would recommend not breaking the behavior of the "default" behavior. Let me explain this: I like to keep very basic features (like "Pick", "Omit") the way they are because they're "basic", working and should stay that way. They're the building blocks for all the rest of the lib. So I'd suggest:
(And I prefer the recursive type references 馃槂) |
We could integrate these changes on the |
I don't think you'll be able to split in such a way that it resuses |
This is annoying if we want to bring this feature to all the types in P... |
I don't understand -
Shouldn't the default be False to match the existing behaviour? This new behaviour should be opt-in to avoid breaking the default behaviour, if I'm understanding this correctly.
It may be annoying, but I think it should be doable - traversing the arrays can be relatively easily done -assuming we use recursive type references. It'll definitely be a lot of extra code, though. If we had type references, we could probably refactor out the "array traversing" code into a separate type and share that with all types in P - but that doesn't exist yet unfortunately :( |
Sorry, I meant to upgrade the non-recursive counterpart as well.
Yes you're right! |
馃帀 eagerly awaiting the 3.7 version - thanks @mcpower! Any way to surface this quickly without forking your My immediate use-case is drilling into arbitrarily deep GraphQL types which can be |
@leebenson I'll see what I can do - I've been putting this off for a while especially as 3.7 wasn't stable - but as the RC was recently released I'll probably look at this again. #60 should make this much easier - it should just be I'll work on implementing this as a full-fledged PR soon (tomorrow, hopefully).
If the change is as easy as I think, you could probably copy the implementation of O.P.Pick, make those changes above and create a utility type in your own project - respecting ts-toolbelt's license, of course. If you need attributions on the modification, you can use "Modifications copyright (C) 2019 mcpower". |
If you're worried about 3.7 support (like I was), and that's your only use case, you can use a variant which doesn't require 3.7 - but only "dives" into 1D arrays (an example implementation should be in the original post). Let me know if you're interested in this - I can probably whip up a utility type for you. |
Thanks @mcpower. I have it working locally in v4.8.24, replacing a few of the internal types with publicly exported variants: import { Any, Tuple, Iteration, Object } from "ts-toolbelt";
type _Pick<
O extends object,
Path extends Tuple.Tuple<Any.Index>,
I extends Iteration.Iteration = Iteration.IterationOf<"0">
> = O extends (infer A)[] // If the object is an array
? A extends object // If the array is of objects
? _Pick<A, Path, I>[] // Pick from those objects
: O // Else, pick array for unions
: Object.Pick<O, Path[Iteration.Pos<I>]> extends infer Picked // Else, pick the first Path
? {
[K in keyof Picked]: Picked[K] extends infer Prop // Needed for the below to be distributive
? Prop extends object // > If it's an object
? Iteration.Pos<I> extends Tuple.LastIndex<Path> // & If it's the target
? Prop // 1-1: Pick it
: _Pick<Prop, Path, Iteration.Next<I>> // 1-0: Continue diving
: Prop // 0: Pick property
: never;
}
: never;
/** Extract out of **`O`** the fields at **`Path`**
* (鈿狅笍 this type is expensive)
* @param O to extract from
* @param Path to be followed
* @returns **`object`**
* @example
* ```ts
* ```
*/
export type Pick<O extends object, Path extends Tuple.Tuple> = _Pick<O, Path>; Not sure if those are exact 1:1 in all cases, but it seems to be working well. For my use-case, I'm trying to modify this to get at just the last path index, so instead of being typed as: {
a: {
b: {
c: {
d: value
}
}
}
} It'd be typed as: {
d: value
} I'm trying to drill into GraphQL Code Generator generated queries, and wind up with a type that represents an arbitrary level of the graph that can be more easily passed around as React props. Related post for posterity: dotansimha/graphql-code-generator#2832 |
Thanks. I'm using TS 3.7 quite extensively for this app, so happy for this to be 3.7 only, but appreciate your offer! |
Unless I'm mistaken, it seems like you want a recursive/path version of O.At instead of O.P.Path. This is surprisingly non-trivial when it comes to nested arrays in the path... To do this with infinite nesting, we need a utility type to get the (nested) inner type of an array. However, this is impossible - see this TS Playground for an example of why it's impossible to implement. However, if we restrict nesting to something absurd like four dimensional nested arrays, it could work, like in this TS Playground. I think we should create a separate issue for this feature (if I'm understanding you correctly!). Judging by the linked graphql-code-generator issue, I presume you'd like to be able to do something like this: type Nested = {
a?: NestedA | NestedA[] | null | number;
z: 'z';
};
type NestedA = {
b?: NestedB | NestedB[] | null | number;
y: 'y';
};
type NestedB = {
c: 'c';
};
// resolves to 'c'
type C = O.P.At<Nested, ['a', 'b', 'c']>; |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This is not an issue anymore thanks to @mcpower |
@mcpower I am going to undo your work in the v7. You will have to use |
No problem. I think using |
I'm not sure I understand how to use this. Is there an example for |
馃崺 Feature Request
Is your feature request related to a problem?
In the APIs I'm working with, I have some nested properties - for example:
Some APIs only give a subset of data - in this case, only
Household.people.name
- which is a perfect fit forO.P.Pick
. However,O.P.Pick
doesn't support arrays natively, which results in types like these:HouseholdSubset.people
isn't an array, it's still an object indexed by number - so we can't use array methods inHouseholdSubset.people
, and we can't pass it to functions expecting an array. In this case, we'd like to somehow get a type of{people: {name: string}[]}
.Describe the solution you'd like
Either modify
O.P.Pick
or create a new type which automatically traverses arrays.I have two solutions in mind:
An example which only works using the first solution:
An example which works for both solutions:
Realistically speaking, most use cases (including all of mine) will only use one dimension, so it may not worth it to require an upgrade to TypeScript 3.7 for a niche feature.
Describe alternatives you've considered
N/A
Teachability, Documentation, Adoption, Migration Strategy
If modifying
O.P.Pick
for this feature, this will be a breaking change for any project usingO.P.Pick
to pick into array properties. There should realistically not be any users affected by this, but it is a breaking change nonetheless.If using the unlimited dimension solution, requiring TypeScript 3.7 will be a huge breaking change for most users.
Notes
I implemented this as a PR, using a different name (O.P.PickA) and using the one dimensional implementation. I realised that the details of this should be discussed in an issue before any PRs should be made - so I made this issue 馃槃
The text was updated successfully, but these errors were encountered: