简体   繁体   English

如何在打字稿界面中迭代可选变量?

[英]How to iterate over optional variables in a typescript interface?

I'm working with a library that provides typescript interfaces with all members as optional and no constructor, like this: 我正在使用一个提供打字稿接口的库,所有成员都是可选的,没有构造函数,如下所示:

export interface ExampleDto {
    a?: string;
    b?: string;
}

Trying to loop the members in a usual way gets nowhere (as the object doesn't have the members, since they're optional): 尝试以常规方式循环成员无济于事(因为对象没有成员,因为它们是可选的):

let ex: ExampleDto = {};
for(let m in ex) {
    console.log(m);
}

How do I loop through ExampleDto and see "a" and "b" without having to construct an actual ExampleDto with all members set? 如何遍历ExampleDto并看到“ a”和“ b”,而不必构造带有所有成员集的实际ExampleDto? Some of these interfaces have a LOT of members. 其中一些接口有很多成员。 I don't care about the value. 我不在乎价值。 I just want to iterate through the optional members names. 我只想遍历可选成员名称。


Came up with the following fix, based on Meirion Hughes explanation. 根据Meirion Hughes的解释提出了以下解决方案。 Each of the interfaces was generated dynamically via Swagger, so I'm adding an empty() function to create a fully populated object. 每个接口都是通过Swagger动态生成的,因此我要添加一个empty()函数来创建一个完全填充的对象。 I went this route to avoid breaking other users of the library: 我这样做是为了避免破坏图书馆的其他用户:

export interface ExampleDto {
  a?: string;
  b?: string;
}
export namespace ExampleDto {
  export function empty(): ExampleDto {
    return {
      a: null,
      b: null,
    }
  }
}

Update 2: Typescript 2.1 provides "keyof" which yields the type of permitted property names. 更新2:Typescript 2.1提供了“ keyof”,它产生了允许的属性名称的类型。 Details here: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html 此处的详细信息: https : //www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html

Interfaces have no run-time construct. 接口没有运行时构造。 So you will have to assign the field for it to exist during run-time. 因此,您将必须分配该字段以使其在运行时存在。 If you want the key to exist, but have a value of undefined / null then you have to initialize it explicitly. 如果您希望键存在,但其值为undefined / null,则必须显式初始化它。 You can enforce this by dropping the optional and allowing it to be of type undefined . 您可以通过删除可选并将其设置为undefined类型来实施此操作。

interface Foo{
  bar: number | undefined;
}

let bad:Foo = {}; // Error - Property 'bar' is missing in type '{}'.

let good:Foo = {bar:undefined}; // OK

for(let key in good) {
    console.log(key);  // prints bar
}

One thing you can do is apply your incomplete optional data on top of a valid instance. 您可以做的一件事是将不完整的可选数据应用于有效实例。 ie create a base version of the instance with all fields set to undefined. 即创建实例的基本版本,并将所有字段设置为未定义。 Then allow a partial instance with some unset properties. 然后,允许部分实例具有一些未设置的属性。 Finally, merge the base and incomplete together to create a restored instance, containing all fields: 最后,将基础和不完整合并在一起,以创建包含所有字段的还原实例:

type Foo = { bar: string | undefined, ray: string | undefined };

let initFoo: Foo = { bar: undefined, ray: undefined };
let incompleteDTO: Partial<Foo> = { ray: "yes" };
let restoredData: Foo = { ...initFoo, ...incompleteDTO };

for (let key in restoredData) {
  console.log(key, restoredData[key]);
}

output: 输出:

bar undefined
ray yes

Finally, this kind of behavior is easier to use via a class: 最后,通过类更易于使用这种行为:

class Foo {
  bar: number | undefined = undefined;
  ray: string | undefined = undefined;

  constructor(init: Partial<Foo>) {
    Object.assign(this, init);
  }
}

let bad: Foo = {}; // Error
let good: Foo = new Foo({ ray: "yes" });

Typescript interfaces aren't actual object or classes, they are only definitions of the structure of javascript objects at runtime. Typescript接口不是实际的对象或类,它们只是运行时javascript对象结构的定义。
The interfaces aren't even being translated into javascript when compiling, and have no constructors. 接口甚至在编译时都没有翻译成javascript,也没有构造函数。

In your code you assigned an empty object into the ex variable, it has no properties. 在代码中,您为ex变量分配了一个空对象,它没有属性。
This will print a : 这将打印a

let ex: ExampleDto = {
    a: "A"
};
for(let m in ex) {
    console.log(m);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM