I'd maintain a "header" object tracking the underlying array's size & how many entries it holds in addition to the pointer to said array where it can readily be resized. Each entry of the array would hold the key, value, & a byte for both their types. The type would also flag empty slots.
Once the array reaches 2/3s full I'd have it reallocate the array and move entry into its new place. If we enlarged the array in-place, check if a value's already there to rehash.
3/4?