I'm having trouble compiling this code snippet:
type F<A> = (a:A)=>A;
class CLAZZ<S extends { [k: string]: any }, K extends keyof S = keyof S>{
constructor(a:S){
this._o=a;
}
_o:S;
set(k:K, f:F<S[K]>){
f(this._o[k]);
}
}
type O = {
pippo: number,
pluto: string | null,
paperino: {[k:string]:boolean}
}
let o = new CLAZZ<O>({"paperino":{}, pluto:null, pippo:1});
o.set("paperino", (paperino)=>({...paperino, "ciccio":true}))
The error occurs on the last line:
Spread types may only be created from object types.
This is because the 'paperino' argument is inferred as
(parameter) paperino: string | number | { [k: string]: boolean; } | null
when I am expecting just
{ [k: string]: boolean; }
Even forcing the parameter type results in an error:
o.set("paperino", (paperino: {[k:string]:boolean})=>({...paperino,"ciccio":true}))
Argument of type '(paperino: { [k: string]: boolean; }) => { ciccio: true; }' is not assignable to parameter of type 'F<string | number | { [k: string]: boolean; } | null>'. Types of parameters 'paperino' and 'a' are incompatible. Type 'string | number | { [k: string]: boolean; } | null' is not assignable to type '{ [k: string]: boolean; }'. Type 'null' is not assignable to type '{ [k: string]: boolean; }'.
Is there a solution other than using "any"?