javascript - Probando el tipo de parámetro de función
Tengo una función así:
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 {};
};
Mis tipos para PageBasic, PostCollection y PostProduct son todos diferentes. Algunos tienen los datos de fields.slug y fields.collection y otros no. Mis declaraciones if me confirman con qué tipo de entrada estoy tratando, por ejemplo, si contentType === 'pageCollection', entonces estoy tratando con el tipo PostCollection. Sin embargo, Typescript no lo sabe. ¿Hay alguna manera de decirle que si mi condición es verdadera, entonces el tipo del parámetro entry es PostCollection o algo así?
La única otra manera que conozco para hacer esto es agregar muchas más declaraciones condicionales para verificar si las claves existen, lo cual parece inútil cuando ya sé que lo estarán basado en mis declaraciones condicionales. por ejemplo:
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 {};
};
Respuesta #1
Sí, puedes: usa una aserción de tipo:
if (contentType ==='pageBasic') {
return { slug: <PageBasic>(entry).fields.slug };
}
También podrías devolver un objeto con condicionales:
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)
};
};
