为什么打字稿允许 referencing/assigning 只读 type/property 可变类型?
Why typescript allows referencing/assigning a readonly type/property by mutable type?
为什么打字稿不强制只读关键字并阻止我们将只读 属性 传递给非只读关键字,这违背了要点
let foo: {
readonly bar: number;
} = {
bar: 123
};
function iMutateFoo(foo: { bar: number }) {
foo.bar = 456;
}
iMutateFoo(foo); // The foo argument is aliased by the foo parameter
console.log(foo.bar); // 456!```
readonly
关键字只是一个ts-compiler检查。话虽如此,您是在告诉编译器 mutate 函数接受一个 non-readonly 参数。
然而,如果你真的输入正确,编译器会报错,例如
type test = { readonly bar: number };
let foo: test = {
bar: 123
};
function iMutateFoo(foo: test) {
foo.bar = 456; // error
}
这是一个 known behavior whose surprising effects inspired an issue originally titled "readonly modifiers are a joke"。问题的简短答案是 "it would have broken backwards compatibility when readonly
was introduced"。长答案来自以下评论:
@ahelsberg said:
In order to ensure backwards compatibility, the readonly
modifier doesn't affect subtype and assignability type relationships of the containing type (but of course it affects assignments to individual properties).
Consider the following code:
interface ArrayLike<T> {
length: number;
[index: number]: T;
}
function foo(array: ArrayLike<string>) {
// Doesn't mutate array
}
var s = "hello";
var a = ["one", "two", "three"];
foo(s); // s has readonly length and index signature
foo(a);
In existing TypeScript code there is no way to indicate if a particular property is intended to be read-only or mutable. In the code above, foo
doesn't mutate the array it is passed, but there is nothing in the code that says it can't. However, now that we've added a readonly
modifier to the length
property and the index signature in the String
interface (because they really are read-only), the foo(s)
call above would be an error if we said that a readonly
property is incompatible with a property without readonly
. Specifically, we can't interpret the absence of a readonly
modifier to mean read-write, we can only say that we don't know. So, if an interface differs from another interface only in the readonly
modifiers on its properties, we have to say that the two interfaces are compatible. Anything else would be a massive breaking change.
好了。如果你想表达你对解决这个问题的支持,你可能想转到那个 GitHub issue 并给它一个或描述你的用例(如果它引人注目且尚未提及)。
总之,希望对您有所帮助;祝你好运!
为什么打字稿不强制只读关键字并阻止我们将只读 属性 传递给非只读关键字,这违背了要点
let foo: {
readonly bar: number;
} = {
bar: 123
};
function iMutateFoo(foo: { bar: number }) {
foo.bar = 456;
}
iMutateFoo(foo); // The foo argument is aliased by the foo parameter
console.log(foo.bar); // 456!```
readonly
关键字只是一个ts-compiler检查。话虽如此,您是在告诉编译器 mutate 函数接受一个 non-readonly 参数。
然而,如果你真的输入正确,编译器会报错,例如
type test = { readonly bar: number };
let foo: test = {
bar: 123
};
function iMutateFoo(foo: test) {
foo.bar = 456; // error
}
这是一个 known behavior whose surprising effects inspired an issue originally titled "readonly modifiers are a joke"。问题的简短答案是 "it would have broken backwards compatibility when readonly
was introduced"。长答案来自以下评论:
@ahelsberg said:
In order to ensure backwards compatibility, the
readonly
modifier doesn't affect subtype and assignability type relationships of the containing type (but of course it affects assignments to individual properties).Consider the following code:
interface ArrayLike<T> { length: number; [index: number]: T; } function foo(array: ArrayLike<string>) { // Doesn't mutate array } var s = "hello"; var a = ["one", "two", "three"]; foo(s); // s has readonly length and index signature foo(a);
In existing TypeScript code there is no way to indicate if a particular property is intended to be read-only or mutable. In the code above,
foo
doesn't mutate the array it is passed, but there is nothing in the code that says it can't. However, now that we've added areadonly
modifier to thelength
property and the index signature in theString
interface (because they really are read-only), thefoo(s)
call above would be an error if we said that areadonly
property is incompatible with a property withoutreadonly
. Specifically, we can't interpret the absence of areadonly
modifier to mean read-write, we can only say that we don't know. So, if an interface differs from another interface only in thereadonly
modifiers on its properties, we have to say that the two interfaces are compatible. Anything else would be a massive breaking change.
好了。如果你想表达你对解决这个问题的支持,你可能想转到那个 GitHub issue 并给它一个或描述你的用例(如果它引人注目且尚未提及)。
总之,希望对您有所帮助;祝你好运!