Open mohaalak opened 3 years ago
If I understand the proposal correctly, it seems you want to have a utility type that can take your Email
and Phone
types as input and produce the ContactInfoToSave
as output, is that right? Something like:
type Email = {id: number, type: "Email", email: string}
type Phone = {id: number, type: "Phone", phone: string}
type MyResult = MyType<Email, Phone>;
//=> type MyResult = {
// id: number;
// type: "Email" | "Phone";
// phone?: string;
// email?: string;
// }
Am I correct? Is this what you want?
If yes, why? Your ContactInfoToSave
type is a superset of Email | Phone
. It allows some "nonsense" values such as:
{
id: 1,
type: 'Email',
phone: '99999999999'
}
Why not just use Email | Phone
?
No I have this type
type ContactInfo = Email | Phone
I work with this on my main data but the server need something like
type ContacInfoToSave = {
type: "Email" | "Phone",
phone?: string;
emailAddress?: string
}
and about "nonsense" if you want to go from "ContactInfo" to "ContactInfoToSave" there will not be any nonsense, but for going from "ContactInfoToSave" to "ContactInfo" there will be some cases and it needs validation, I use io ts for validation and decoding.
let's save we want to map ContactInfo
to ContactInfoToSave
const map = (c: ContactInfo): ContactInfoToSave => ({
type: c.type,
emailAddress: c.email // there is no c.email
})
there is no c.email
or c.phone
you should just create some switch case for every type to create a ContactInfoToSave
.
[...] but the server need something like [...]
Why does the server need that? Why can't the server use Email | Phone
?
[...] but the server need something like [...]
Why does the server need that? Why can't the server use
Email | Phone
?
your types should not be dependent of what your server request you should have your types then when you want to connect to server or database you should map it to them.
server or database should not dictate how you express your models and types.
[...] but the server need something like [...]
Why does the server need that? Why can't the server use
Email | Phone
?
you can see that server accept emailAddress
but I have email
when you want to map you should pattern match on type then return the value but with this type you have all of types that server wants without pattern matching on type
field.
Problem
let's say we have these types
and we want to send it to an API or save it do database but the API accepts something like this
UnionToIntersecion doesnot work
if we use
UnionToIntersection
we getnever
cause thetype
cannot be merged to one it's like when you want to intersectUnionToIntersection<string | number>
it cannot be done.Solution
I have a solution for it
Let me explain how does it work. The default
Omit
andPick
utility type does not go inside each union type, but it's going to pick only the common type that available in every union type. alsokeyof
works exactly like that only will export the keys is common in each union;so
now if we pick these two keys
Now we want to omit
id
andtype
but we want to go inside each union, so we can remove it. for this we can use Distributive conditional types hence theDistributiveOmit
.After that we got something like
now with
UnionToIntersection
we can merge all of this together and make theContactInfoToSave
I did not pull request because I thought let's discuss it a little about it. like if the
TaggedUnionToIntersection
is a good name or if we want to no common between union bePartial
or not.Upvote & Fund