TypeScript交叉类型和只读属性

3

我正试图使用TypeScript编写一段代码,其模式可简化为以下形式:

function test(x: {theFlag: boolean} & {readonly theFlag: boolean} ){
    x.theFlag = true;
}

但是在这一行代码 x.theFlag = true; 上,我收到以下错误:

[ts] 无法分配给 'theFlag',因为它是一个常量或只读属性。

我不知道为什么TypeScript会报错。我认为逻辑上应该是允许的。

有没有好的解决方法来实现我想要做的事情?

我正在使用TypeScript版本2.7.2。

1个回答

2

我认为编译器是在谨慎处理,因为属性在其中一个组成类型中是只读的,所以在交集中也是只读的。

在2.8版本中,您可以轻松地创建一个类型,从任何属性中删除readonly

type Mutable<T> = { -readonly [P in keyof T]: T[P]};
function test(x: Mutable<{theFlag: boolean} & {readonly theFlag: boolean}> ){
  x.theFlag = true;
}

在2.7及以下版本中,我认为以下Mutable的定义应该能够解决问题。我没有使用任何2.8语法,但我没有旧版本进行测试。
type MutableHelper<T, TNames extends string> = { [P in TNames]: (T & { [name: string]: never })[P]};
type Mutable<T> = MutableHelper<T, keyof T>;

关于Typescript采取保守策略,这是我的心理模型:{readonly theFlag: boolean} 是具有getter的 theFlag 值的集合,而 {theFlag: boolean} 则是具有getter和setter的 theFlag 值的集合。由于后者是前者的子集,它们的交集应该与 {theFlag: boolean} 相同。 - Arash
根据基本集合论,{getter,setter}和{getter}的交集是{getter}。 - Hisham H M
@HishamHM 不是我理解的那样:想象一个 type T={a:...}U={b:...}。类型上的每个键都代表了对 {} 的约束。T&U 并不是取 的交集(它不是 {}),而是取 约束 的交集 -- 一个类型要属于这个交集,它必须同时满足 T 和 U,因此 T&U={a,b}。这同样适用于 get/set 的例子 -- 要同时满足 {get} & {get, set},它必须包含约束 get 和约束 set:因此 {x} & {readonly x} = {x} - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接