I am creating a function called formatAddress
which accepts an address object and property map object as input and outputs the mapped address.
function formatAddress(address, map): MappedAddressOutput {
...
}
type MappedAddressOutput = AnyObject[typeof AddressMap[keyof typeof AddressMap]];
interface Address {
addressLine1: string;
addressLine2: string;
city: string;
province: string;
postalCode: string;
}
const AddressMap = {
addressLine1: "address1",
addressLine2: "address2",
city: "city",
province: "province",
postalCode: "postalCode"
};
type IndexSignature = string | number | symbol;
type AnyObject = { [key: IndexSignature]: any };
If I wish to transform the MappedAddressOutput
as the code below:
type MappedAddressOutput = ObjectValueAsKey<AddressMap>
How can I implement ObjectValueAsKey type?
CodePudding user response:
Use a generic type parameter so you can use the given map in the return type:
function formatAddress<To extends Record<keyof Address, string>>(address: Address, map: To): {
[K in keyof Address as To[K]]: Address[K];
} {
return Object.entries(address).map(([k, v]) => [map[k as keyof typeof map], v]);
}
Then when you use it, you have to make sure the map is inferred literally. The simplest way to do that is to use as const
:
interface Address {
addressLine1: string;
addressLine2: string;
city: string;
province: string;
postalCode: string;
}
const exampleMap = {
addressLine1: "address1",
addressLine2: "address2",
city: "city",
province: "province",
postalCode: "postalCode"
} as const;
const result = formatAddress({
addressLine1: "",
addressLine2: "",
city: "",
province: "",
postalCode: "",
}, exampleMap);
and now the type of result
is
{
address1: string;
address2: string;
city: string;
province: string;
postalCode: string;
}