如果我想在Javascript中以编程方式将一个属性分配给一个对象,我会这样做:

var obj = {};
obj.prop = "value";

但在TypeScript中,这会产生一个错误:

属性“prop”在类型为“{}”的值上不存在

我应该如何在TypeScript中分配任何新属性给对象?


当前回答

这是Object的一个特殊版本。赋值,它会在每次属性更改时自动调整变量类型。不需要额外的变量、类型断言、显式类型或对象副本:

function assign<T, U>(target: T, source: U): asserts target is T & U {
    Object.assign(target, source)
}

const obj = {};
assign(obj, { prop1: "foo" })
//  const obj now has type { prop1: string; }
obj.prop1 // string
assign(obj, { prop2: 42 })
//  const obj now has type { prop1: string; prop2: number; }
obj.prop2 // number

//  const obj: { prop1: "foo", prop2: 42 }

注意:示例使用TS 3.7断言函数。与Object.assign不同,assign的返回类型是void。

其他回答

最好的做法是使用安全输入,我建议你:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}

你可以用这个:

this.model = Object.assign(this.model, { newProp: 0 });

通过将任何类型的对象类型转换为'any'来存储任何新属性:

var extend = <any>myObject;
extend.NewProperty = anotherObject;

稍后,你可以通过将扩展对象转换回'any'来检索它:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;

唯一完全类型安全的解决方案是这个,但是有点啰嗦,并且迫使您创建多个对象。

如果你必须先创建一个空对象,那么从这两个解决方案中选择一个。记住,每次你使用as,你就失去了安全。

安全解决方案

对象类型在getObject中是安全的,这意味着对象。A的类型为字符串| undefined

interface Example {
  a: string;
  b: number;
}

function getObject() {
  const object: Partial<Example> = {};
  object.a = 'one';
  object.b = 1;
  return object as Example;
}

短期解决方案

对象类型在getObject中是不安全的,这意味着对象。即使在赋值之前,A的类型也是string。

interface Example {
  a: string;
  b: number;
}

function getObject() {
  const object = {} as Example;
  object.a = 'one';
  object.b = 1;
  return object;
}

最简单的是

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"