I have various documents that all share a set of common fields.
I'm trying to create a function that will populate the common fields while taking the unique fields as an input, resulting in a complete document.
I have this working, but right now I need to manually specify the final type. I'm curious if there is a way in typescript to infer the final type based on the fields that are passed in (or throw an error if the passed in fields don't match any of the known doc types.
Here is the code I have right now for this:
type DocA = {
id: string,
createdAt: string,
onlyDocA: string
}
type DocB = {
id: string,
createdAt: string,
onlyDocB: string
}
type AllDocTypes = DocA | DocB
export const createBaseDocument = <DocType extends AllDocTypes>(
fields: Omit<DocType, 'id' | 'createdAt'>,
): DocType => {
const createdAt = new Date();
return {
id: generateId(),
createdAt: createdAt.toString(),
...fields,
} as DocType
}
function generateId(): string {
return 'id'
}
// testA should be of type `DocA`
const testA = createBaseDocument({ id: 'a', createdAt: '123', onlyDocA: 'hello'})
// testA should be of type `DocB`
const testB = createBaseDocument({ id: 'a', createdAt: '123', onlyDocB: 'hello'})
// testC should throw a type error
const testC = createBaseDocument({ id: 'a', createdAt: '123', onlyDocC: 'hello'})
// testD should throw a type error
const testD = createBaseDocument({ id: 'a', createdAt: '123', onlyDocA: 'hello', onlyDocB: 'hello'})