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

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

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

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

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


当前回答

索引类型

可以将obj表示为任意值,但这违背了使用typescript的全部目的。obj ={}表示obj是一个对象。把它标记为任何都没有意义。为了实现所需的一致性,可以按照如下方式定义接口。

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

或使之紧凑:

var obj: {[k: string]: any} = {};

LooseObject可以接受任何字符串作为键,任何类型作为值的字段。

obj.prop = "value";
obj.prop2 = 88;

这个解决方案的真正优雅之处在于,您可以在接口中包含类型安全字段。

interface MyType {
    typesafeProp1?: number,
    requiredProp1: string,
    [key: string]: any
}

var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number

obj.prop = "value";
obj.prop2 = 88;

记录<Keys,Type>实用程序类型

更新(2020年8月):@transang在评论中提到了这一点

Record<Keys,Type>是typescript中的Utility类型。对于属性名未知的键-值对,它是一种更简洁的替代方法。 值得注意的是,Record<Keys,Type>是{[k: Keys]: Type}的命名别名,其中Keys和Type是泛型。 在我看来,这一点值得一提

相比较而言,

var obj: {[k: string]: any} = {};

就变成了

var obj: Record<string,any> = {}

MyType现在可以通过扩展Record类型来定义

interface MyType extends Record<string,any> {
    typesafeProp1?: number,
    requiredProp1: string,
}

虽然这回答了最初的问题,但@GreeneCreations的回答可能会从另一个角度来解决这个问题。

其他回答

我倾向于把任何放在另一边,即var foo:IFoo = <任何>{};所以这样的东西仍然是类型安全的:

interface IFoo{
    bar:string;
    baz:string;
    boo:string;     
}

// How I tend to intialize 
var foo:IFoo = <any>{};

foo.bar = "asdf";
foo.baz = "boo";
foo.boo = "boo";

// the following is an error, 
// so you haven't lost type safety
foo.bar = 123; 

或者你可以将这些属性标记为可选:

interface IFoo{
    bar?:string;
    baz?:string;
    boo?:string;    
}

// Now your simple initialization works
var foo:IFoo = {};

在网上试试

在TypeScript中动态地为对象分配属性。

你只需要像这样使用typescript接口:

interface IValue {
    prop1: string;
    prop2: string;
}

interface IType {
    [code: string]: IValue;
}

你可以这样使用它

var obj: IType = {};
obj['code1'] = { 
    prop1: 'prop 1 value', 
    prop2: 'prop 2 value' 
};

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

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

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

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

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

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

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

declare var obj: any;