I’m working with TypeScript and trying to ensure that the return type of a function accurately reflects the properties that are present in the input object after mapping. Specifically, I want TypeScript to enforce type constraints so that accessing non-existent properties on the returned object results in a compile-time error.
My current code:
enum MetadataKeys {
NATURE = 'nature',
BUDGET_YEAR = 'budget_year',
}
const metadataKeysMapper: Record<string, MetadataKeys> = {
cdNatureza: MetadataKeys.NATURE,
natureza: MetadataKeys.NATURE,
cd_natureza: MetadataKeys.NATURE,
SiglaNatureza: MetadataKeys.NATURE,
nuAnoOrcamento: MetadataKeys.BUDGET_YEAR,
ordem_orcamentaria: MetadataKeys.BUDGET_YEAR,
nu_ano_orcamento: MetadataKeys.BUDGET_YEAR,
Orcamento: MetadataKeys.BUDGET_YEAR,
anoOrcamento: MetadataKeys.BUDGET_YEAR,
};
type MetadataResponse<T> = {
[K in keyof T as K extends keyof typeof metadataKeysMapper
? (typeof metadataKeysMapper)[K]
: never]: K extends keyof typeof metadataKeysMapper ? T[K] : never;
};
export function processMetadata<T extends Record<string, any>>(
metadata: T,
): MetadataResponse<T> {
const processedMetadata: Partial<Record<MetadataKeys, any>> = {};
for (const [key, value] of Object.entries(metadata)) {
if (key in metadataKeysMapper && value) {
processedMetadata[metadataKeysMapper[key]] = value;
}
}
return processedMetadata as MetadataResponse<T>;
}
Expected result:
const input = { natureza: 'comum' };
const result = processMetadata(input);
// Accessing valid property
console.log(result.nature); // should work
// Accessing invalid property
console.log(result.budget_year); // should raise a TypeScript error
Problem:
The TypeScript compiler is not raising an error when accessing non-existent properties on the result object. I expected accessing result.budget_year to cause a compile-time error.
Leonardo Rocha Ferreira is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.