I know that, we can use Readonly< T> to redeclare all fields of T as readonly, as in: [Typescript: extending an interface and redeclaring the existing fields as readonly
What about nested fields? For example:
interface School {
teachers: Array<Teacher>;
students: Array<Student>;
}
interface Teacher {
teacherId: number;
personInfo: PersonInfo;
}
interface Student {
studentId: number;
personInfo: PersonInfo;
}
interface PersonInfo {
name: string;
age: number
}
How to create a SchoolReadonly type, in which all nested fields are readonly.
A simple test case:
var s: SchoolReadonly = {
teachers: [{teacherId: 1, personInfo: {name: "John", age: 40}}],
students: [{studentId: 1, personInfo: {name: "Dan", age: 20}}]
}
s.teachers[0].personInfo.name = "John2"; //should produce readonly error
s.students[0].personInfo.age = 22; //should produce readonly error
As a constraint, I do not want to add Readonly directly to the School, Teacher, Student and PersonInfo interfaces.
You can use generics and type aliases, it's a lot of code, but it will do the trick:
(code in playground)
Edit
If you want
s.teachers[0] = nul
to fail then you need to also change theArray
toReadonlyArray
, so:The rest is the same, but then:
True, it's not a simple solution and is very verbose, but I don't think that a simple generic solution exists, at least for now, for the problem.
Consider:
This works great as long as the object has only other simple objects:
But if you introduce an array:
Then:
It probably isn't an easy problem to solve.