如果我想在Javascript中以编程方式将一个属性分配给一个对象,我会这样做:
var obj = {};
obj.prop = "value";
但在TypeScript中,这会产生一个错误:
属性“prop”在类型为“{}”的值上不存在
我应该如何在TypeScript中分配任何新属性给对象?
如果我想在Javascript中以编程方式将一个属性分配给一个对象,我会这样做:
var obj = {};
obj.prop = "value";
但在TypeScript中,这会产生一个错误:
属性“prop”在类型为“{}”的值上不存在
我应该如何在TypeScript中分配任何新属性给对象?
当前回答
只需这样做,您就可以添加或使用任何属性。(我使用的typescript版本为“typescript”:“~4.5.5”)
let contextItem = {} as any;
现在,您可以添加任何属性并在任何地方使用它。就像
contextItem.studentName = "kushal";
之后你可以这样使用它:
console.log(contextItem.studentName);
其他回答
当一个Map可以接受固定类型的任意值时,使用ES6 Map,否则使用可选属性
我想这就是我的指导方针。ES6映射可以在typescript中完成,如在typescript中提到的:ES6映射
可选属性的主要用例是函数的“选项”参数:使用命名参数JavaScript(基于typescript)在这种情况下,我们确实提前知道允许的属性的确切列表,所以最明智的事情是只定义一个显式接口,只是使任何可选的可选与?正如在https://stackoverflow.com/a/18444150/895245上提到的,尽可能多地进行类型检查:
const assert = require('assert')
interface myfuncOpts {
myInt: number,
myString?: string,
}
function myfunc({
myInt,
myString,
}: myfuncOpts) {
return `${myInt} ${myString}`
}
const opts: myfuncOpts = { myInt: 1 }
if (process.argv.length > 2) {
opts.myString = 'abc'
}
assert.strictEqual(
myfunc(opts),
'1 abc'
)
然后,当它是真正任意的(无限多个可能的键)并且具有固定类型时,我将使用Map,例如:
const assert = require('assert')
const integerNames = new Map<number, string>([[1, 'one']])
integerNames.set(2, 'two')
assert.strictEqual(integerNames.get(1), 'one')
assert.strictEqual(integerNames.get(2), 'two')
测试:
"dependencies": {
"@types/node": "^16.11.13",
"typescript": "^4.5.4"
}
通过将任何类型的对象类型转换为'any'来存储任何新属性:
var extend = <any>myObject;
extend.NewProperty = anotherObject;
稍后,你可以通过将扩展对象转换回'any'来检索它:
var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
我倾向于把任何放在另一边,即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 = {};
在网上试试
为了保证类型是Object(即键值对),使用:
const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
唯一完全类型安全的解决方案是这个,但是有点啰嗦,并且迫使您创建多个对象。
如果你必须先创建一个空对象,那么从这两个解决方案中选择一个。记住,每次你使用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;
}