I have an interface in my application:
interface Asset {
id: string;
internal_id: string;
usage: number;
}
that is part of a post interface:
interface Post {
asset: Asset;
}
I also have an interface that is for a post draft, where the asset object might only be partially constructed
interface PostDraft {
asset: Asset;
}
I want to allow a PostDraft
object to have a partial asset object while still checking types on the properties that are there (so I don't want to just swap it out with any
).
I basically want a way to be able to generate the following:
interface AssetDraft {
id?: string;
internal_id?: string;
usage?: number;
}
without entirely re-defining the Asset
interface. Is there a way to do this? If not, what would the smart way to arrange my types in this situation be?
This isn't possible in TypeScript < 2.1 without creating an additional interface with optional properties; however, this is possible by using mapped types in TypeScript 2.1+.
To do this, use the Partial<T>
type which TypeScript provides by default.
interface PostDraft {
asset: Partial<Asset>;
}
Now all the properties on asset
are optional, which will allow you to do the following:
const postDraft: PostDraft = {
asset: {
id: "some-id"
}
};
About Partial<T>
Partial<T>
is defined as a mapped type that makes every property in the provided type optional (using the ?
token).
type Partial<T> = {
[P in keyof T]?: T[P];
};
Read more about mapped types here and in the handbook.
Deep Partial
If you want a partial implementation that works recursively on objects then you can use the following type in TS 4.1+:
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};