Simple Local Storage object with typings
A simple typed localStorage object with namespaced keys and validated values.
2 min read
Updated
A compact typed wrapper around localStorage that keeps keys namespaced and values validated. The usage example and the implementation are below.
Usage
ts
const store = createLocalStorage('MY_PREFIX', {
USERNAME: '',
TOKEN: 'default-value',
// ...
});
// reading
console.log(store.USERNAME === localStorage.getItem('MY_PREFIX_USERNAME')); // false
console.log(localStorage.getItem('MY_PREFIX_USERNAME') === null); // true
console.log(store.USERNAME === ''); // true
console.log(localStorage.getItem('MY_PREFIX_TOKEN') === 'default-value'); // true
// setting
store.USERNAME = 'mandela-madiba';
console.log(localStorage.getItem('MY_PREFIX_USERNAME') === 'mandela-madiba'); // true
console.log(store.USERNAME === localStorage.getItem('MY_PREFIX_USERNAME')); // true
// deleting
delete store.USERNAME;
console.log(localStorage.getItem('MY_PREFIX_USERNAME') === null); // true
console.log(store.USERNAME === ''); // true
localstorage.ts
typescript
/*
* This file is subject to the Creative Commons Attribution 4.0 International (CC BY 4.0) license.
* Author: Sébastien Demanou
* To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/legalcode
*/
export function createLocalStorage<T extends Record<string, string>>(prefix: string, properties: T): T {
function key(prop: string) {
return `${prefix}_${prop}`;
}
const proxy = new Proxy(properties, {
get(target, property: string, receiver) {
return target[property];
},
set(target: Record<string, string>, property: string, value, receiver) {
localStorage.setItem(key(property), value);
target[property] = value;
return true;
},
deleteProperty(target: Record<string, string>, property: string) {
localStorage.removeItem(key(property));
target[property] = '';
return true;
},
});
// preload properties
for (const property in properties) {
const obj = properties as Record<string, string>;
const value = localStorage.getItem(key(property)) || properties[property];
if (value) {
(proxy as Record<string, string>)[property] = value;
} else {
obj[property] = value;
}
}
return proxy;
}