Javascript 打字稿迭代接口属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45670705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:09:44  来源:igfitidea点击:

typescript iterate interface properties

javascripttypescript

提问by Chris

I need to map interface properties to objects:

我需要将接口属性映射到对象:

    interface Activity {
        id: string,
        title: string,
        body: string,
        json: Object
    }

I currently do:

我目前这样做:

   headers: Array<Object> = [
            { text: 'id', value: 'id' },
            { text: 'title', value: 'title' },
            { text: 'body', value: 'body' },
            { text: 'json', value: 'json' }
        ]

This gets very repetitive. What I would like is something like this:

这变得非常重复。我想要的是这样的:

   headers: Array<Object> = Activity.keys.map(key => {
       return { text: key, value: key }
   })

回答by Nitzan Tomer

You can't, interfaces are only for compile time because javascript doesn't support it.

您不能,接口仅用于编译时,因为 javascript 不支持它。

What you can do is something like:

你可以做的是:

const Activity = {
    id: "",
    title: "",
    body: "",
    json: {}
}

type Activity = typeof Activity;
const headers: Array<Object> = Object.keys(Activity).map(key => {
    return { text: key, value: key }
});

(code in playground)

操场上的代码

回答by Vladyslav Zavalykhatko

If you are okay with having it added during a compile time and you are using TypeScript >= 2.4.1, you can try the way proposed here.

如果您可以在编译期间添加它,并且您使用的是 TypeScript >= 2.4.1,则可以尝试此处建议的方式。

Basically, you should add the ts-transformer-keys dependency, custom transformer, like a basic one and you'll be able to list the properties like this:

基本上,您应该添加ts-transformer-keys 依赖项自定义转换器,就像基本的一样,您将能够列出如下属性:

import { keys } from 'ts-transformer-keys';

interface Props {
    id: string;
    name: string;
    age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); // ['id', 'name', 'age']

回答by qballer

if you would like to keep the interface ability you can do the following, @Nitzan Tomer is right. Interfaces are part of the type system, hence they are only relevant in compile time as they are omitted in the transpiled code.

如果您想保留界面功能,您可以执行以下操作,@Nitzan Tomer 是对的。接口是类型系统的一部分,因此它们仅在编译时相关,因为它们在转译代码中被省略。

class Activity {
    public id: string = '';
    public title: string = '';
    public body: string = '' ;
    public json: Object = {};
}

let activity = new Activity()

const headers: Array<Object> = Object.keys(Activity).map(key => {
    return { text: key, value: key }
});

console.log(JSON.stringify(headers))

回答by T. Dayya

This approach might be a bit overkill, but i use it since i need JSON schemas anyway for validating the back end's response structure. Getting the keys from interfaces is just a nice side-effect of converting typescript interfaces into json schemas:

这种方法可能有点矫枉过正,但我​​使用它,因为无论如何我都需要 JSON 模式来验证后端的响应结构。从接口获取键只是将 typescript 接口转换为 json 模式的一个很好的副作用:

Using a typescript to json schema converter, one could get interfaces keys along with their types. The resulting json objects are large and verbose, so a parsing helper function could come in handy to recursively constructing simpler JS objects the way you want out of them. The good news is that a json schema always has the same structure, so it's easy to navigate.

使用打字稿到 json 模式转换器,可以获取接口键及其类型。生成的 json 对象又大又冗长,因此解析辅助函数可以派上用场,以您想要的方式递归构建更简单的 JS 对象。好消息是 json 模式始终具有相同的结构,因此易于导航。