下面的Javascript代码显示{ x: 1 }
:
var foo = 'x';
var a = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
console.log(a);
类似地,我需要在Typescript中动态构建一个对象,换句话说,当我创建该对象时,我不知道它的成员是什么。
我在Typescript中尝试过此操作,但是它不起作用:
let foo = 'x';
let a = {};
if (foo == 'x')
a.x = 1; // <-- transpilation fails here
else
a.y = 2; // <-- transpilation fails here
console.log(a);
错误是Property 'x' does not exist on type '{}'.
是否可以在Typescript中动态创建对象?
答案 0 :(得分:4)
TypeScript需要在声明变量时了解对象将具有的字段。默认情况下,根据您分配的内容来推断类型,因为您分配了{}
,所以a
将是没有属性的类型。您可以将a
的类型声明为适合您需要的内容:
var foo = 'x';
var a : { x?: number; y?:number} = {}; // Both x and y are optional, hence the ?
if (foo == 'x')
a.x = 1;
else
a.y = 2;
console.log(a);
也可以使用a: any
,但是您应该避免使用它,因为它会关闭a
上的所有检查,这可能不是您想要的,因为打字稿的重点是尽可能多地检查。除非您不知道值的类型和键名,否则我会避免使用any
。
如果您在编译时不知道键是什么(可能是基于用户输入或服务调用),则还可以使用index signature,该键至少会检查值的类型已验证。例如,仅允许数字值但任何键的类型如下:
var foo = 'x';
var a : { [n: string]: number} = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
console.log(a);
答案 1 :(得分:3)
如果您确实知道所有可能的字段 ,但您不知道要设置的 ,则可以使用Partial<T>
,其中无需创建新接口并将:?
放在任何地方,因为您可能希望继承其属性并非都是可选的类型/接口:
interface A {
x: number;
y: number;
z: string;
}
let foo = 'x';
let a: Partial<A> = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
如果您不提前知道什么字段可以是 ,因为TypeScript仅提前存在(在编译阶段),因此另一种选择是将其声明为{{ 3}}类型。
let foo = 'x';
let a: any = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
然而,这很少是一种理想的方法,因为它完全禁用了类型检查,从而使使用TypeScript进行修饰的目的无法实现。