I have a function like so:
type Entry = PageBasic | PageHome | PostCollection | PostProduct;
export default (entry: Entry): Params => {
const contentType = entry.sys.contentType.sys.id;
if (contentType ==='pageBasic') {
return { slug: entry.fields.slug };
}
if (contentType === 'pageCollection') {
return { collection: entry.fields.slug };
}
if (contentType === 'postProduct') return {
collection: entry.fields.collection.fields.slug,
product: entry.fields.slug,
};
return {};
};
My types for PageBasic, PostCollection and PostProduct are all different. Some have the fields.slug and fields.collection data and some don't. My if statements confirm to me which entry type I'm dealing with e.g. if the contentType === 'pageCollection' then I'm dealing with PostCollection type. However Typescript doesn't know that. Is there a way for me to tell it if my condition is true, then the type of the entry param is PostCollection or something?
The only other way I know to do this is adding lots more conditional statements to check if the keys exist, which seems pointless when I already know they will based on my conditional statements. e.g:
export default (entry: Entry): Params => {
const contentType = entry.sys.contentType.sys.id;
if (contentType === CT_PAGE_BASIC) {
if ('slug' in entry.fields) return { slug: entry.fields.slug };
}
if (contentType === CT_POST_COLLECTION) {
if ('slug' in entry.fields) return { collection: entry.fields.slug };
}
if (contentType === CT_POST_PRODUCT) return {
...'collection' in entry.fields && { collection: entry.fields.collection.fields.slug },
...'slug' in entry.fields && { product: entry.fields.slug },
};
return {};
};
Yes you can - use a type assertion:
if (contentType ==='pageBasic') {
return { slug: <PageBasic>(entry).fields.slug };
}
You could also return an object with conditionals:
export default (entry: Entry): Params => {
const contentType = entry.sys.contentType.sys.id;
return {
...(contentType ==='pageBasic' ? { slug: (<PageBasic>entry).fields.slug } : 0),
...(contentType === 'pageCollection' ? { collection: (<PostCollection>entry).fields.slug } : 0),
...(contentType === 'postProduct' ? { collection: (<PostProduct>entry).fields.collection.fields.slug, product: (<PostProduct>entry).fields.slug } : 0)
};
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With