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> { //... } }
chrome? What islocalStoragesupposed 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 forObject.entriesand the like; see this q and/or this q. ⊛ If I make multiple guesses then I get this version; does that work or no?localStorageequal todefaultStorage, thenlocalStoragehas the same keys with just updated values. ② I checked your example, the next line withObject.entriesworks without error:this.storage[key as string & keyof T] = this.createStore(key, value).chrome? ② Yes, you could work around it that way too, although note thatvalueis of typeanyso 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 forObject.entries()? Or am I missing something about the question?anydoesn't matter inObject.entries. Because there is match key to key. Indeed, I tried extracttypeofdefaultStorage[key], but magic with typeof keyof too hard. ⊛ Yes, error connect withObject.entries/keys.