Reputation: 726
I have a very complex type defined in my Typescript:
export type DraftCamp = DeepPartial<CampForm> & {
isActive: false
} & FilesExtension
Which actually is just an interface with some nested values - no unions. Is there anyway to take a peek into this type and see how it actually looks like? Can I do this without manually following all the other types it references?
Upvotes: 1
Views: 361
Reputation: 250366
You can use an Id
type that maps over the intersection. There is no guarantee as to what will expand out a mapped type, but this type currently does the trick:
type Id<T> = {} & {
[P in keyof T]: Id<T[P]>
}
Using Id
on an intersection will flatten it out:
type FilesExtension = {
ext: string
}
// Naive implementation, just filler
type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>
}
type CampForm = {
foo: {
bar: string
}
baz: {
bars: string[]
}
}
type Id<T> = {} & {
[P in keyof T]: Id<T[P]>
}
export type DraftCamp = Id<DeepPartial<CampForm> & {
isActive: false
} & FilesExtension>
// Hover over DraftCamp and you will see the expanded version of it:
// type DraftCamp = {
// foo?: {
// bar?: string | undefined;
// } | undefined;
// baz?: {
// bars?: (string | undefined)[] | undefined;
// } | undefined;
// isActive: false;
// ext: string;
// }
Note: I have to warn you, there are some arcane assignability rules that differ between an intersection and a flattened out type with the same members, but it does mostly work the same. The idea is that Id
is much like a console.log
useful for debugging, but don't leave it lying around in production code
Upvotes: 3