type GetLastElementType<T extends any[]> = T[2]
NOTE: There might be a way to pick the type of the last item in an array of any length, but I didn't know.
function toGetterSetter<T extends Record<string, any>, K extends keyof T>(dict: T):
{ [U in K as `get_${U & string}`]: () => T[U] } &
{ [V in K as `set_${V & string}`]: (v: T[V]) => void; }
{
const getterSetter = {} as any;
for (const [k, v] of Object.entries(dict)) {
getterSetter[`get_${k}`] = () => v;
getterSetter[`set_${k}`] = (v: any) => (dict as any)[k] = v;
}
return getterSetter;
}
const STATE = {
AL: 'AL', // Alabama
AK: 'AK', // Alaska
AZ: 'AZ', // Arizona
AR: 'AR', // Arkansas
} as const;
const STATE_DATA: Record<string, { [K in keyof typeof STATE]: any }> = {
POST_CODE: {
[STATE.AL]: '01',
[STATE.AK]: '02',
[STATE.AZ]: '03',
[STATE.AR]: '04',
},
AREA: {
[STATE.AL]: 100,
[STATE.AK]: 200,
[STATE.AZ]: 300,
[STATE.AR]: 400,
},
CITIES: {
[STATE.AL]: ['city 1', 'city 2'],
[STATE.AK]: ['city 3', 'city 4'],
[STATE.AZ]: ['city 5', 'city 6'],
[STATE.AR]: ['city 7', 'city 8'],
}
};
function getStateData<D extends typeof STATE_DATA, K extends keyof D>(data: D[K], state: keyof typeof STATE) {
return data[state]
}
// use cases
getStateData(STATE_DATA.POST_CODE, STATE.AL) // 01
getStateData(STATE_DATA.AREA, STATE.AL) // 100
getStateData(STATE_DATA.CITIES, STATE.AZ) // ['city 7', 'city 8']