The challenge for today is to take this union type here type user type post type comment.
export type Entity =
| {
type: "user"
}
| {
type: "post"
}
| {
type: "comment"
}
And then dynamically add id to the type which is going to be userId postId and commentId. As you can see bellow, we are manually defining the types of those id properties.
type EntityWithId =
| {
type: "user"
userId: string
}
| {
type: "post"
postId: string
}
| {
type: "comment"
commentId: string
}
We can automate this with TypeScript
First we'll use the [Key in Type] syntax to iterate over our Entity type and set the type property to the key which we've named EntityType.
type EntityWithId = {
[EntityType in Entity["type"]]: {
type: EntityType
}
}
We'll want to turn this object into a union type. We do this by applying an index operation to the object. In this case we'll use [Entity["type"]] to get the value of the type property.
type EntityWithId = {
[EntityType in Entity["type"]]: {
type: EntityType
}
}[Entity["type"]]
and this means. now that we now have our type comment or type user
const result = (EntityWithId = {
type: "comment",
})
But we haven't really added anything here. We just sort of created the same type again.
What we need to do is say that we want type property AND our id property. We can create the dynamic id property using Record utility type. This is used to define a key and the type of its value. We'll make the key dynamic by using string interpolation.
type EntityWithId = {
[EntityType in Entity["type"]]: {
type: EntityType
} & Record<`${EntityType}Id`, string>
}[Entity["type"]]
So now in our result object we can set commentId to a string.
const result: EntityWithId = {
type: "comment",
commentId: "123",
}
so in EntityWithId where we set the type and use & Record..., we're saying we have have the type of EntityType AND the Record which is another way of saying we have an object with a key of ${EntityType}Id and a value of string
We can then create objects for user and post.
const userResult: EntityWithId = {
type: "user",
userId: "123",
}
const postResult: EntityWithId = {
type: "post",
postId: "123",
}
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.