Typescript 如何描述函数通过引用改变对象?

Typescript 如何描述函数通过引用改变对象?,typescript,Typescript,我有一个通过引用修改对象的函数: 函数addProp(对象、值){ object.foo=值; } 如何告诉TypeScript在调用addProp函数后,对象值改变了它的类型?我希望有这样的代码: interface WithProp<T> { foo: T; } function addProp<T1 extends object, T2>(object: T1 mutatesTo (T1 & WithProp<T2>), value: T

我有一个通过引用修改对象的函数:

函数addProp(对象、值){
object.foo=值;
}
如何告诉TypeScript在调用
addProp
函数后,
对象
值改变了它的类型?我希望有这样的代码:

interface WithProp<T> {
  foo: T;
}

function addProp<T1 extends object, T2>(object: T1 mutatesTo (T1 & WithProp<T2>), value: T2) {
  object.foo = value;
}

const obj = { bar: 'baz' };
obj.foo; // TS: error
addProp(obj, 123);
obj.foo; // TS: ok
function addProp<T1 extends object, T2>(
    o: T1,
    value: T2
): asserts o is T1 & WithProp<T2> {
    (o as T1 & WithProp<T2>).foo = value;
}
与prop的接口{
foo:T;
}
函数addProp(对象:T1 mutatesTo(T1&WithProp),值:T2){
object.foo=值;
}
const obj={bar:'baz'};
obj.foo;//TS:错误
addProp(obj,123);
obj.foo;//TS:好的

类型系统实际上并不适合变量类型的变异。它确实用于缩小变量类型,至少在某些代码块中是这样,但直到最近,还没有办法编写
addProp()
来触发这种基于控制流的缩小

引入TypeScript 3.7来表示不返回值但防止无效状态的函数。他们是非常新的,有一些,所以要警告

但是您现在可以做的是将
addProp()
表示为断言函数,该函数表示
T1
类型的输入现在被断言为较窄的
T1类型&WithProp
。在这种情况下,如果输入不是该类型,函数实现不会抛出错误,而是通过添加属性使其成为该类型。但对于类型系统来说都是一样的。不管怎样,它看起来是这样的:

interface WithProp<T> {
  foo: T;
}

function addProp<T1 extends object, T2>(object: T1 mutatesTo (T1 & WithProp<T2>), value: T2) {
  object.foo = value;
}

const obj = { bar: 'baz' };
obj.foo; // TS: error
addProp(obj, 123);
obj.foo; // TS: ok
function addProp<T1 extends object, T2>(
    o: T1,
    value: T2
): asserts o is T1 & WithProp<T2> {
    (o as T1 & WithProp<T2>).foo = value;
}
请注意,这种缩小是控制流分析的结果,它在分配时被重置,因此您可能会惊讶于以下操作不起作用(请注意,我将
let
而不是上面的
const
):

但是,这是我能得到的最接近于表示类型系统中这种突变的方法。好的,希望这有帮助;祝你好运


我们是不是要从这里开始讨论使用typescript的原因?我认为您需要向函数添加一个返回类型,该类型返回经过修改的对象,并且我认为不可能出现您描述的“TS编译器”返回错误,因为“TS编译器”无法知道在运行时对象会发生什么。最好是让编译器知道对象可能会更改,然后需要向其添加多个类型。