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

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

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

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

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


当前回答

我很惊讶没有一个答案引用Object。赋值,因为这是我在考虑JavaScript中的“组合”时使用的技术。

在TypeScript中,它可以像预期的那样工作:

interface IExisting {
    userName: string
}

interface INewStuff {
    email: string
}

const existingObject: IExisting = {
    userName: "jsmith"
}

const objectWithAllProps: IExisting & INewStuff = Object.assign({}, existingObject, {
    email: "jsmith@someplace.com"
})

console.log(objectWithAllProps.email); // jsmith@someplace.com

优势

始终保持类型安全,因为您根本不需要使用任何类型 使用TypeScript的聚合类型(在声明objectWithAllProps类型时用&表示),这清楚地表明我们正在动态地(即动态地)组合一个新类型。

需要注意的事情

Object.assign has it's own unique aspects (that are well known to most experienced JS devs) that should be considered when writing TypeScript. It can be used in a mutable fashion, or an immutable manner (I demonstrate the immutable way above, which means that existingObject stays untouched and therefore doesn't have an email property. For most functional-style programmers, that's a good thing since the result is the only new change). Object.assign works the best when you have flatter objects. If you are combining two nested objects that contain nullable properties, you can end up overwriting truthy values with undefined. If you watch out for the order of the Object.assign arguments, you should be fine.

其他回答

您可以添加此声明来屏蔽警告。

declare var obj: any;

尽管编译器抱怨它仍然应该按照你的要求输出它。然而,这是可行的。

const s = {};
s['prop'] = true;

可以通过将成员添加到现有对象

扩大类型(读取:扩展/专门化接口) 将原始对象转换为扩展类型 将成员添加到对象中

interface IEnhancedPromise<T> extends Promise<T> {
    sayHello(): void;
}

const p = Promise.resolve("Peter");

const enhancedPromise = p as IEnhancedPromise<string>;

enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value));

// eventually prints "Hello Peter"
enhancedPromise.sayHello();

最简单的是

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

为了保证类型是Object(即键值对),使用:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'