1

After previous question, occurs an error with new type CustomStorageFor. How to fix the error inside initStorage()? Typescript version 5.1.6

// Type 'string' cannot be used to index type 'CustomStorageFor<T>'
this.storage[key] = this.createStore(key, value)
type CustomStorageFor<T> = { [K in keyof T]: CustomStore<T[K]> } & {
    [key: string]: CustomStore<T>
}

type CustomStore<T> = {
    value: T,
    init: (value: T) => void;
    set: (value: T) => void;
}

class LiveStorage<T extends object> {

    private defaultStorage: T
    storage: CustomStorageFor<T>

    constructor(defaultStorage: T) {
        this.defaultStorage = defaultStorage
        this.storage = {} as CustomStorageFor<T>
        this.initStorage()
    }

    private async initStorage() {
        Object.entries(this.defaultStorage).forEach(([key, value]) => { 
            // key: string, value: any
            this.storage[key] = this.createStore(key, value)
        })
    }

    private createStore<ValueType>(key: string, value: ValueType): CustomStore<ValueType> {
        //...
    }
}
Viewed
  • 1,159
  • 3
  • 16
  • 43
  • 1
    ① Can you [edit] the code to be a [mre] that doesn't have an apparent dependency on `chrome`? What is `localStorage` supposed to be? I can't really make much progress without resolving that, or making guesses about it. ② This looks like it has little to do with mapped types and a lot to do with TS's types for `Object.entries` and the like; see [this q](https://stackoverflow.com/q/62053739/2887218) and/or [this q](https://stackoverflow.com/q/52856496/2887218). ⊛ If I make multiple guesses then I get [this version](https://tsplay.dev/wQbe1N); does that work or no? – jcalz Aug 13 '23 at 20:23
  • @jcalz ① in first time `localStorage` equal to `defaultStorage`, then `localStorage` has the same keys with just updated values. ② I checked your example, the next line with `Object.entries` works without error: `this.storage[key as string & keyof T] = this.createStore(key, value)`. – Viewed Aug 14 '23 at 06:01
  • ① Could you please [edit] the code so that it doesn't rely on `chrome`? ② Yes, you could work around it that way too, although note that `value` is of type `any` so it's a little less safe to do it that way. ⊛ Do you agree that the issue isn't really about mapped types and has more to do with TS's typings for `Object.entries()`? Or am I missing something about the question? – jcalz Aug 14 '23 at 14:07
  • @jcalz ② types of value with `any` doesn't matter in `Object.entries`. Because there is match key to key. Indeed, I tried extract `type` of `defaultStorage[key]`, but magic with typeof keyof too hard. ⊛ Yes, error connect with `Object.entries/keys`. – Viewed Aug 14 '23 at 18:59

0 Answers0