You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Change property modifier in mapped type based on condition #32562
Possibly relevant comment from another somewhat related issue (#31581, about detecting such modifiers)
I'd be interested in more streamlined manipulation of modifiers in mapped types. Detecting `readonly` and optional properties is indeed a bunch of hoop jumping, and then if you want to selectively *alter* the modifiers, you need to split the mapping into pieces and intersect them:
typeSelectivePartial<T,KextendskeyofT>=Partial<Pick<T,K>>&Required<Pick<T,Exclude<keyofT,K>>>extends
infer U ? {[PinkeyofU]: U[P]} : never;typeFoo=SelectivePartial<{a: string,b: number,c?: boolean},'b'>// type Foo = { b?: number | undefined; a: string; c: boolean; }
It would be a lot nicer to essentially read and selectively write modifiers inside the mapping directly. (Note the word "selectively"; the current support for altering modifiers is all-or-nothing ).
Reacted by Sean M. Vieira, Alexey Gerasimov, Adam, David Stemmer, John and Thorr Stevens
Zod's object types need this. Whether a key is optional depends on the schema at that key, so the output type is two filtered mapped types intersected. That shape has two problems a single mapped type doesn't.
Generic code can't index the output with keyof T, and every optional key moves to the end, in hovers and in .d.ts output. With { [K in keyof T]: T[K]["output"] } both go away, but there's no way to make some of those keys optional. Putting an all-optional copy of the shape first keeps the declared order, but it breaks self-referential schemas with 2615 circularity errors.
Activity
pleerock commentedon Jul 25, 2019
Okay, I think I found the way it can be implemented right now:Looks likeunknownsaves us here.Issue can be closed, but I would like team to pay attention on the scalability of the current approach.EDIT 1: No, I was too happy about it. It doesn't work.
EDIT 2: Okay, found a resolution:
AnyhowStep commentedon Jul 25, 2019
Just note that your types might look a little "ugly" in the tooltip. It'll still work just fine, though.
If you want to make it look a little better (maybe for debugging or something),
Then,
When you hover over
Blah, you should see the two objects merged into oneI'm on mobile and can't test it but I think the above works. I'll check again when I get home
jcalz commentedon Jul 25, 2019
Possibly relevant comment from another somewhat related issue (#31581, about detecting such modifiers)
codinsonn commentedon Jul 25, 2021
This works, but also seems to turn types like
Dateinto{ toString: () => string, ... }Would there be a way to prevent this?
colinhacks commentedon Oct 9, 2026
Zod's object types need this. Whether a key is optional depends on the schema at that key, so the output type is two filtered mapped types intersected. That shape has two problems a single mapped type doesn't.
Generic code can't index the output with
keyof T, and every optional key moves to the end, in hovers and in .d.ts output. With{ [K in keyof T]: T[K]["output"] }both go away, but there's no way to make some of those keys optional. Putting an all-optional copy of the shape first keeps the declared order, but it breaks self-referential schemas with 2615 circularity errors.Still the case on 7.1.0-dev.20261006.1.