diff --git a/src/types/mapper.ts b/src/types/mapper.ts index 89d7599..b4786f4 100644 --- a/src/types/mapper.ts +++ b/src/types/mapper.ts @@ -1,15 +1,29 @@ -import { ExtractSourceKeys, ExtractSources, ExtractDestinationKeys, ExtractDestinations, Profile } from '@/types/profile' +import { ExtractSourceKeys, Profile } from '@/types/profile' + +/** + * Registered profiles grouped once by source key, then destination key, so each `map` call is two + * property lookups rather than a fresh pass over every registered profile. + */ +type ProfileIndex = { + [TSourceKey in ExtractSourceKeys]: { + [TMatch in Extract as TMatch extends Profile ? TMatch['destinationKey'] : never]: TMatch + } +} + +type ProfileSource = TProfile extends Profile ? TSource : never + +type ProfileDestination = TProfile extends Profile ? TDestination : never export type Mapper = { register: (profiles: Profile[] | readonly Profile[] | Profile) => void, clear: () => void, has: (sourceKey: string, destinationKey: string) => boolean, map: < - TSourceKey extends ExtractSourceKeys, - TDestinationKey extends ExtractDestinationKeys - > (sourceKey: TSourceKey, source: ExtractSources, destinationKey: TDestinationKey) => ExtractDestinations, + TSourceKey extends keyof ProfileIndex & string, + TDestinationKey extends keyof ProfileIndex[TSourceKey] & string + > (sourceKey: TSourceKey, source: ProfileSource[TSourceKey][TDestinationKey]>, destinationKey: TDestinationKey) => ProfileDestination[TSourceKey][TDestinationKey]>, mapMany: < - TSourceKey extends ExtractSourceKeys, - TDestinationKey extends ExtractDestinationKeys - > (sourceKey: TSourceKey, sourceArray: ExtractSources[], destinationKey: TDestinationKey) => ExtractDestinations[], + TSourceKey extends keyof ProfileIndex & string, + TDestinationKey extends keyof ProfileIndex[TSourceKey] & string + > (sourceKey: TSourceKey, sourceArray: ProfileSource[TSourceKey][TDestinationKey]>[], destinationKey: TDestinationKey) => ProfileDestination[TSourceKey][TDestinationKey]>[], }