At this typescript playground I have written a minimal Immutable (recursive readonly) type and a Store interface which stores an Immutable.
Currently there is a compile error for the read() and write() functions of my partitioned store class, which I would like to resolve by properly annotating the types, and not making type assertions. Here are the top-level definitions.
interface Store<State>{
read:() => Immutable<State>
write:(state:Immutable<State>) => Immutable<State>
}
export type ImmutableObject<T> =
{
readonly [K in keyof T]: Immutable<T[K]>;
}
;
export type Immutable<T> = T extends object
? ImmutableObject<T>
: T extends string | number | boolean | null
? Readonly<T>
: never;
My problem arises when I derive a partitioned sub-store from a store. That means just selecting a sub-part of the State using one of its declared keys, and making a Store out of that.
This is my draft implementation which requires the commented assertion to suppress compile errors...
class BasicStorePartition<SuperState, Key extends keyof SuperState>
implements Store<SuperState[Key]>{
constructor(
readonly store: Store<SuperState>,
readonly key: Key,
) {}
//this line requires the commented type assertion in order to compile
read = () => this.store.read()[this.key] // as unknown as Immutable<SuperState[Key]>
write = (state:Immutable<SuperState[Key]>) => {
this.store.write({
...this.store.read(),
[this.key]:state
});
return this.read()
}
}
The compile errors reported are as below. I would expect these to resolve to the same type and no idea where the string as a key has come from, since no key is annotated that way in the source...
Type 'ImmutableObject<SuperState[string]>' is not assignable to type 'Immutable<SuperState[Key]>'
Type 'Immutable<SuperState>[Key]' is not assignable to type 'Immutable<SuperState[Key]>'
It is possible to fix the compilation by simply asserting the type information like...
as unknown as Immutable<SuperState[Key]>
I want to resolve this compile error so the types resolve and align to the expected readonly types, without me having to bypass the compiler. Can anyone see a way to do this?
Welcome any other observations about improving the approach.