This problem can be solved easily using a JavaScript/TypeScript feature called "maps" which support both insertion order (like lists) and constant-time performance for basic operations like `get`, `set`, `has` etc. Here the solution would involve creating an LRU cache class in TypeScript:
 
```ts
export class LruCache<K, V> {
    private readonly map: Map<K, V>; // This holds our cache data

    constructor(private capacity: number) { // The provided capacity for the cache
        if (capacity <= 0 || Number.isNaN(capacity)) throw new Error('Capacity must be a positive integer');
        this.map = new Map();
    }  
   
    get(key: K): V | undefined {
        const hasKey = this.map.has(key); // Check if the key exists in our cache 
        if (hasKey) {
            // To return a value, we need to first delete (so as not to disrupt the order of usage) and re-set the item:
            const val = this.map.get(key);
          this.map.delete(key); // Needed because Set is Order-preserving and we want this key at the end
          this.map.set(key, val as V); 
        }
        return hasKey ? this.map.get(key) : undefined;  // Return get result if entry exists, otherwise return undefined to indicate a miss         
    }
    
    set(key: K, value: V): void { // Set operation of LRU cache.
        if (this.map.has(key)) this.map.delete(key);   // If updating an existing key, first delete it to maintain order
      else if (this.map.size === this.capacity)  // If we are adding a new K-V pair and our cache is full…
            this.map.delete(this.map.keys().next().value); // Delete the least recently used entry which would be the first item in Map’s iterator order (Map keeps insertion order)
      this.map.set(key, value);  // Now add our new or updated K-V pair to cache
    } 
   
    get size(): number { // Returns the current size of our cache
        return this.map.size;     
    }
}
```