为什么 Readonly<T> 可以分配给 T,但 ReadonlyArray<T> 不能分配给 Array<T>?

ale*_*son 5 typescript

type Foo = {a: number}
let obj: Foo = {} as Readonly<Foo>
let arr: number[] = [] as ReadonlyArray<number>
Run Code Online (Sandbox Code Playgroud)

我知道该ReadonlyArray类型删除了任何变异Array方法,这意味着只读数组不遵守数组的预期接口。

但我不明白为什么只读对象被认为可以安全地传递给需要可变对象的函数。从技术上讲,只读对象缺少隐式 setter 方法,因此它并没有真正遵守预期的可变接口。

游乐场链接

Kar*_*ski 3

ReadonlyArray事实上,是另一种类型,因此ArrayReadonlyArray在结构上是不同的。正如您所注意到的, 的实例ReadonlyArray缺少一些方法,例如pushpop

它不适用于对象。没有单独的ReadonlyObject也没有ReadonlyObjectConstructor。许多不应该被允许的操作被允许:

type Foo = {a: number}

let mutable: Foo = { a: 0 };
let immutable: Readonly<Foo> = { a: 0 };

/**
 * Both work without error.
 */
mutable = immutable;
immutable = mutable;

/**
 * These two work as well.
 */
Object.assign(immutable, { foo: 1 });
Object.defineProperty(immutable, 'bar', {
    value: 2
});
Run Code Online (Sandbox Code Playgroud)

TypeScript 使用结构类型系统。形状完全相同的两个对象可以相互分配。但是,readonly修饰符不会影响结构,只会影响行为。