只读属性使用
readonly修饰,表示属性只能在初始化时赋值,之后不能修改。
interface User {
readonly id: number
name: string
}
const user: User = {
id: 1,
name: "张三"
}
user.name = "李四" // 正确
user.id = 2 // 错误:只读属性不能修改
interface Entity {
readonly id: number
name: string
createdAt: Date
}
function updateEntity(entity: Entity, name: string): Entity {
return {
...entity,
name
// id 和 createdAt 保持不变
}
}
interface Config {
readonly apiKey: string
readonly endpoint: string
timeout?: number
}
const config: Config = {
apiKey: "abc123",
endpoint: "/api"
}
config.timeout = 5000 // 正确
config.apiKey = "xyz" // 错误:只读属性
interface Point {
readonly x: number
readonly y: number
}
function move(point: Point, dx: number, dy: number): Point {
return {
x: point.x + dx,
y: point.y + dy
}
}
const origin: Point = { x: 0, y: 0 }
const moved = move(origin, 10, 20)
只读数组,不能修改:
const numbers: ReadonlyArray<number> = [1, 2, 3]
numbers.push(4) // 错误
numbers[0] = 10 // 错误
numbers.length = 0 // 错误
const newNumbers = [...numbers, 4] // 正确:创建新数组
const names: readonly string[] = ["张三", "李四"]
将所有属性变为只读:
interface User {
id: number
name: string
email: string
}
const user: Readonly<User> = {
id: 1,
name: "张三",
email: "zhangsan@example.com"
}
user.name = "李四" // 错误:所有属性都是只读的
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]
}
interface User {
id: number
profile: {
name: string
address: {
city: string
}
}
}
const user: DeepReadonly<User> = {
id: 1,
profile: {
name: "张三",
address: {
city: "北京"
}
}
}
user.profile.name = "李四" // 错误:深层只读
interface State {
readonly users: readonly User[]
readonly loading: boolean
readonly error: string | null
}
interface User {
readonly id: number
readonly name: string
}
function reducer(state: State, action: Action): State {
switch (action.type) {
case "ADD_USER":
return {
...state,
users: [...state.users, action.payload]
}
default:
return state
}
}
interface Config {
readonly apiKey: string
readonly endpoint: string
}
function fetchData(config: Config): void {
// config.apiKey = "hacked" // 错误:无法修改
console.log(`请求 ${config.endpoint}`)
}
type ReadonlyTuple = readonly [string, number]
const tuple: ReadonlyTuple = ["hello", 10]
tuple[0] = "world" // 错误:只读
tuple.push("extra") // 错误:只读
readonly 只影响第一层:
interface User {
readonly profile: {
name: string
}
}
const user: User = {
profile: { name: "张三" }
}
user.profile = { name: "李四" } // 错误
user.profile.name = "李四" // 正确:profile 内部不受影响
readonly 只在编译时检查:
interface User {
readonly id: number
}
const user: User = { id: 1 }
(user as any).id = 2 // 运行时可以修改
// const 用于变量
const user = { id: 1 }
user = { id: 2 } // 错误:不能重新赋值
user.id = 2 // 正确:可以修改属性
// readonly 用于属性
interface User {
readonly id: number
}
const user: User = { id: 1 }
user.id = 2 // 错误:属性只读