“只读"的用法在打字稿中 [英] Usages of "readonly" in TypeScript

查看:54
本文介绍了“只读"的用法在打字稿中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个用法很简单:作为一个契约,函数doSomething声明它不会改变接收到的参数.

This usage is very simple: as a contract, the function doSomething declares it doesn't mutate the received parameter.

interface Counter {
  name: string
  value: number
}

function doSomething(c: Readonly<Counter>) {
  // ...
}

let c = {
  name: "abc",
  value: 123
}
doSomething(c)
// Here we are sure that 'c.name' is "abc" and 'c.value' is '123'

用法 2:工厂声明其输出不可修改

使用此代码:

interface Counter {
  readonly name: string
  readonly value: number
  inc(): number
}

function counterFactory(name: string): Counter {
  let value = 0
  return {
    get name() {
      return name
    },
    get value() {
      return value
    },
    inc() {
      return ++value
    }
  }
}

我们这里有一个成员只读值,不能直接从外部修改.但是成员 inc() 可以改变该值.此外,成员 value 被声明为 readonly 但它的值正在改变.

We have here a member readonly value that cannot be modified directly from the outside. But a member inc() can mutate the value. Also, the member value is declared as readonly but its value is changing.

我想知道在成员 value 上使用 readonly 是否是一个好的方法.语法没问题.但是这个例子在 TypeScript 中语义正确吗?这是修饰符 readonly 的用途吗?

I would like to know if this use of readonly on the member value is a good way to proceed. The syntax is OK. But is this example semantically correct in TypeScript? Is that what the modifier readonly is for?

推荐答案

属性上的 readonly 关键字并不能确保属性值是恒定的.没有对应的 TypeScript.对于 readonly 属性,我们唯一可以确定的是:

The readonly keyword on a property does not ensure that the property value is constant. There's no TypeScript equivalent for that. The only things we can be sure with a readonly property are:

  1. 它的值不能从消费者端改变→用法1.
  2. 它可以是仅获取属性的推断类型→ 用法 2.请注意,如果未定义 counterFactory 返回类型,则推断与 完全一样Counter 接口,见下面代码中的(A).
  3. 它的值只能设置一次,并且只能在对象构造期间设置→参见下面的 (B).
  1. Its value can't be changed from the consumer side → usage 1.
  2. It can be the inferred type of a get-only property → usage 2. Note that, if the counterFactory return type is not defined, it is inferred exactly like the Counter interface, see (A) in the code below.
  3. Its value can be set only once and only during the object construction → see (B) below.

代码示例:

// (A) Usage 2 using type inference
const counter = counterFactory('foo');
type Counter = typeof counter; // Produce the exact same type as the previous `Counter` interface
counter.value = 10; // [Ts Error] Can not assign to 'value' because it is a constant or read-only property

// (B) Readonly property initialization
// (B1) With an object literal + interface 
const manualCounter: Counter = { name: 'bar', value: 2, inc: () => 0 };
manualCounter.value = 3; // [Ts Error] Can not assign...

// (B2) With a class
class Foo {
  constructor(public name: string, public readonly value: number) { }
  inc() {
    return ++this.value; // [Ts Error] Can not assign...
  }
}

const foo = new Foo('bar', 3);
foo.value = 4; // [Ts Error] Can not assign...

// (C) Circumvent TypeScript
Object.assign(foo, { value: 4 }); // → No error neither in Ts, nor at runtime

这真的很令人困惑,因为它几乎就像一个常量属性!用法 2 和案例 C 证明不是.

It's really confusing because it's almost like a constant property! The usage 2 and the case C prove it's not.

这篇关于“只读"的用法在打字稿中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆