-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Preserve tuples when mapping with as
clauses
#40586
Comments
I believe this was a conscious design decision, and in this case I think compacting a tuple to a shorter length is pretty surprising to me. I would have expected a sparse array type in this case. |
My use-case was for handling |
We could also have |
This would be awesome if it could also preserve tuple labels after filtering. I got a version of curry that preserves tuple labels (from the curried function's params) by splitting up the individual parameters and then re-joining them after sorting - it's painful. |
I kind of expect tuples/arrays to stay tuples/arrays if the Now maybe if we suppress indices at the end it can produce a shortened tuple, since the type KillTwo<T> = { [K in keyof T as Exclude<K, "2">]: T[K] };
type A = KillTwo<["a", "b", "c", "d"]>; // ["a", "b", undefined, "d"] or ["a", "b", never, "d"] or ??
type B = KillTwo<["a", "b", "c"]>; // ["a", "b"] |
@jcalz Why not allow to delete entries, to create a real filter? That's how the current feature works with objects. On top of that, if we want the behavior you describe type KillTwo<T> = { [K in keyof T]: K extends "2" ? never : T[K] }; This is the reason why I'm asking for
type KillTwo<T> = { [K in keyof T as Exclude<K, "2">]: T[K] };
type test0 = KillTwo<[1, 2, 3]> // [1, 2]
type test1 = KillTwo<(1 | 2 | 3)[]> // (1 | 2 | 3)[] Arrays don't have specific keys,
type Filter2<T> = { [K in keyof T as T[K] extends 2 ? never : K]: T[K] };
type test0 = Filter2<[1, 2, 3]> // [1, 3]
type test1 = Filter2<(1 | 2 | 3)[]> // (1 | 3)[] Both array and tuple will match the condition |
Does it, though? I think you and I must have different ideas on what is considered a filter. Here's an object: type MyOmit<T, K extends PropertyKey> = { [P in keyof T as Exclude<P, K>]: T[P] };
type Hmm = MyOmit<{ zero: "a", one: "b", two: "c", three: "d" }, "two"> // { zero: "a"; one: "b"; three: "d"; } I would be exceptionally surprised if what came out were type AlsoHmm = MyOmit<["a", "b", "c", "d"], "2"> // ???
I would love to be able to manipulate tuples at the type level, but on what grounds would you argue that |
I justified (to myself) that
|
I find myself mostly agreeing with all those points, so maybe we're talking past each other? I'm going to try one more time and then stop: I am in favor of But deleting numeric keys from an array does not logically result in a shorter filtered array; it results in a sparse array of the same length: // as a mapped type
type FilterNumbers<T> = {
[K in keyof T as T[K] extends number ? never : K]: T[K];
}
// as a mapped array/object
function filterNumbers(t: { [k: string]: any }) {
const ret: { [k: string]: any } = Array.isArray(t) ? [] : {};
for (let k in t) (typeof t[k] === "number") ? (delete ret[k]) : (ret[k] = t[k]);
return ret;
}
console.log(filterNumbers({ one: "a", two: 2, three: "b", four: 3, five: "c" }));
// {one: "a", three: "b", five: "c"}
console.log(filterNumbers(["a", 2, "b", 3, "c"]));
// ["a", , "b", ,"c"] The automatic reindexing you're talking about which turns a sparse array into a shorter array sounds like a great thing to have in the type system, but I just don't see how mapped types with It certainly can't be done by a straightforward reading of It really feels like Anders gave us a screwdriver and we are now trying to use it to drive nails into a wall. But for that I want a hammer, not a screwdriver which auto-detects nails and sprouts a hammer head. Honestly, though, if such a screwdriver-with-optional-hammer-abilities were given to us, I'm sure I'd use it too. And maybe even be happy about it. But I'd sure feel awkward when explaining it to people on Stack Overflow. Anyway, good luck with this feature request! |
I'm reading |
Search Terms
#tuple #mapped #as #clause #preserve
Suggestion
New mapped type's
as
clause allows one to filter the entries of an object. Basic mapped types preserve the shape of a tuple but not when used with the newas
clause:Use Cases
Examples
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: