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

时间:2019-01-11 23:36:37

标签: typescript

type Foo = {a: number}
let obj: Foo = {} as Readonly<Foo>
let arr: number[] = [] as ReadonlyArray<number>

我了解到ReadonlyArray类型删除了所有可变的Array方法,这意味着只读数组未遵守预期的数组接口。

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

Playground link

1 个答案:

答案 0 :(得分:2)

ReadonlyArray实际上是另一种类型,因此ArrayReadonlyArray在结构上是不同的。如您所见,ReadonlyArray的实例缺少某些方法,例如pushpop

它与对象不同。没有单独的ReadonlyObjectReadonlyObjectConstructor。允许执行许多不应允许的操作:

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
});

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