Repository navigation
Update Pick to use new key remapping in mapped types #41383
Description
Activity
- addedExperimentation NeededSomeone needs to try this out to see what happensSomeone needs to try this out to see what happensSuggestionAn idea for TypeScriptAn idea for TypeScript
on Nov 11, 2020 RyanCavanaugh commented
on Nov 11, 2020 MemberMore actionsI'm curious what would happen if we did that
Ryan Cavanaugh (@RyanCavanaugh) I ran the tests with the updated definition; 17 failed (11 conformance and 6 compiler). Looking at the baselines, I was able to distill one problem with the new definition to:
type Pick<T, K extends keyof T> = { [P in keyof T as Extract<P, K>]: T[P] }; type Assert<T, U extends T> = U; type X<T, K extends keyof T> = Assert<Pick<T, K>, T>; // ^ // Errors, "Type 'T' does not satisfy the constraint 'Pick<T, K>'"
I haven't looked through all of the baselines in detail to see if there are errors beyond that, though I suspect there are.
Perhaps
Pickshould be left as-is, and people who want interfaces involving it can define their own. Maybe add aPickInterface?Also, what's the reasoning behind error 2312 (an interface can only extend an object type or intersection of object types with statically known members)? With the new
asclause, many types that would appear to not have statically known members are allowed (like below). If types like these can have seemingly dynamic members, why can't interfaces extend the more general format of{ [K in X]: Y }?type Record1<K extends keyof any, V> = { [_K in "" as K]: V } interface RecordInterface<K extends keyof any, V> extends Record1<K, V> { }
For one thing I noticed this fixes issues with
OmitorPick+ intersection types in some cases. I'm not smart enough to know what this is called, but when aPickorOmittype is fed into certain generics, it gets reduced or simplified in ways I don't fully understand. I've seen it in various cases, but here's a playground example.You can see that passing an omit type into a remapped type causes an issue, but this new way of doing it fixes the issue. I wish I understood why, but perhaps someone could shed some light on it.
Brian Frichette (@bfricka) The problem in that scenario boils down to
Omit's definition:type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
Because
Ahas an index signature, that becomesPick<A, string | number>. Homomorphic mapped types, on the other hand, have special casing for index signatures that maps them correctly.#41966 looks like it might be relevant to your scenario.
Reacted by Brian Frichette
Search Terms
pick omit key remapping
Suggestion
Update
Pickinlib.d.tsto be:It is currently defined as:
Use Cases
With this new definition, typescript can statically analyze the keys, which allows interfaces to extends these types.
Examples
Playground Link
Checklist
My suggestion meets these guidelines: