I wanted to return a readonly value from a function but then found that Readonly<T> can be assigned to anything of type T which is not what I wanted. Now I am trying to make a generic type which is readonly (only 1st level) such that it cannot be assigned to a non-readonly of same type.
I checked issue 13002 and 13347 with no luck. Then I stumbled upon this answer and tried to modify it like this -
type NonObjectAndFn =
| null
| undefined
| string
| number
| boolean
| symbol
| bigint
type AnyFunction = (...args: any[]) => any
type Frozen<T> =
T extends NonObjectAndFn ? T :
T extends object | AnyFunction ? FrozenObject<T> :
T
type FrozenObject<T> = {
readonly [K in keyof T]: T[K];
}
export function freeze<T>(obj: T): Frozen<T> {
if(obj == undefined) { // 1st
return obj;
} else if(typeof obj == "function" || typeof obj == "object") { // 2dn
// freeze and proxy then
return frozenObj as Frozen<T>;
} else { // 3rd
return obj;
}
}
Issue is typescript is giving error for 1st and 3rd block returns. I can't figure out why this is happening since Frozen<T> should be undefined or null for 1st block and since 2nd block checks for functions and objects everything else in NonObjectAndFn should fall to 3rd block and should satisfy Frozen<T>'s conditions right?
It's a tricky question, as we have to clarify some things. First of all - why would you try to restrict that assignment? Having some type of
T, it's perfectly reasonable to be able to assign to itReadonly<T>, but not the other way around. As I can see, you would like to propagate that Readonlyness to the first variable, but that's just not possible to change that type at this point, so I would approach the problem from a different angle. Why you ever allow thatTnot to beReadonly? Could you please provide a more detailed explanation of what's going on? Maybe that whole fighting with a type system isn't worth it?