I have this type:
type User = {
id: string;
name?: string;
email?: string;
}
And I would like to construct a similar type with name
non optional:
type UserWithName = {
id: string;
name: string;
email?: string;
}
Instead of repeating the type as I did above, how can I construct UserWithName
from User
with generic utility types?
Required almost does the job but it sets all properties as non-optional, while I just want to set one property.
CodePudding user response:
You can use interfaces instead:
interface User {
id: string;
name?: string;
email?: string;
}
interface UserWithName extends User {
name: string;
}
Now you've built on the User
type, but overwritten the name
property to be mandatory. Check out this typescript playground - a UserWithName
that doesn't have a name property will error.
CodePudding user response:
If you check the source for the Required
type, it's this:
type Required<T> = {
[P in keyof T]-?: T[P]
}
The same syntax can be used to construct a generic type that will give you what you want:
type User = {
id: string
name?: string
email?: string
}
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }
type UserWithName = WithRequired<User, 'name'>
// error: missing name
const user: UserWithName = {
id: '12345',
}