Intro
I have only added "readonly" into Array type before.
But I found that it can be used for other things.
So I will try "readonly" in this time.
Environments
- Node.js ver.16.10.0
- TypeScript ver.4.4.3
readonly array
I can set array as readonly.
const readonlyTexts: readonly string[] = [];
I can use it as declaration, arguments, return value, and so on.
Except I can't reassign value, it has a little differences with default array.
const mutableTexts: string[] = [];
// OK
mutableTexts.push('Hello');
const readonlyTexts: readonly string[] = [];
// compile error
readonlyTexts.push('Hello');
In TypeScript world, readonly array and default array are separated.
So I can't use a readonly array value as a default array value.
function init(): void {
const mutableTexts: string[] = [];
// OK
mutableTexts.push('Hello');
// OK
editArrayValue(mutableTexts);
const readonlyTexts: readonly string[] = [];
// compile error
editArrayValue(readonlyTexts);
}
function editArrayValue(values: string[]): void {
values.push('World');
}
init();
But I can use a default array value as a readonly array value.
function init(): void {
const mutableTexts: string[] = [];
...
// OK
logArrayValue(mutableTexts);
const readonlyTexts: readonly string[] = [];
// OK
logArrayValue(readonlyTexts);
}
...
function logArrayValue(values: readonly string[]): void {
for(const v of values) {
console.log(v);
}
}
init();
type, interface
I can set properties of type and interface as readonly.
type MutableType = {
id: number,
name: string,
values: string[]
};
type ImmutableType = {
readonly id: number,
readonly name: string,
readonly values: string[]
};
function init(): void {
const mutableValue: MutableType = {
id: 0,
name: 'Example',
values: [],
};
// OK
mutableValue.id = 2;
const immutableValue: ImmutableType = {
id: 0,
name: 'Example',
values: [],
};
// compile error
immutableValue.id = 2;
}
In this sample, I can create the "ImmutableType" in more simple way.
type MutableType = {
id: number,
name: string,
values: string[]
};
type ImmutableType = {
readonly [p in keyof MutableType]: MutableType[p]
};
...
I can set the object properties types as readonly by "as const".
const immutableValue = {
id: 0,
name: 'Example',
values: [],
} as const;
// compile error
immutableValue.id = 2;
It only for avoiding reassign value.
Because the readonly value is as same as the default value.
So I can reassign like below.
...
function init(): void {
...
const immutableValue: ImmutableType = {
id: 0,
name: 'Example',
values: [],
};
editValue(immutableValue);
// name becomes "Hello world!'
console.log(immutableValue);
}
function editValue(value: MutableType): void {
value.name = 'Hello world!';
}
...
So I think setting arguments as readonly is more important than setting return values as readonly.
ReadOnly
I can use "readonly" keyword into only array for using as arguments, return value, property types.
But as I wrote above, I should set readonly for all types if I could.
So I use "Readonly" for do it.
...
function editValue(value: Readonly<MutableType>): void {
// compile error
value.name = 'Hello world!';
}
...
One important thing is than it only works for "object" type.
...
function init(): void {
const immutableValue: ImmutableType = {
id: 0,
name: 'Example',
values: [],
};
editName(immutableValue.name);
// name value is "Example"
console.log(immutableValue);
}
function editName(name: Readonly<string>): void {
// OK
name = 'Hello world' ;
}
...
So I must copy the value as a new const variable.
...
function editName(name: Readonly<string>): void {
const targetName = name;
// compile error
targetName = 'Hello world' ;
}
...
Top comments (0)