如何在 TypeScript 中添加索引签名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48773010/
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-10-21 05:13:32  来源:igfitidea点击:

How to add index signature in TypeScript

javascriptarraystypescriptindex-signature

提问by Bethany

I am trying to use reduce with Typescript to reach a total count of incoming messages. I'm confused on how to add an index signature. I keep getting the error: " Element implicitly has an 'any' type because type '{}' has no index signature." on variables newArray and counts[k]. I have read through several similar questions but have not figured out how to apply them to my specific scenario. I am new to JavaScript and TypeScript.

我正在尝试使用 reduce 和 Typescript 来达到传入消息的总数。我对如何添加索引签名感到困惑。我不断收到错误消息:“元素隐式具有 'any' 类型,因为类型 '{}' 没有索引签名。” 在变量 newArray 和 counts[k] 上。我已经阅读了几个类似的问题,但还没有弄清楚如何将它们应用于我的特定场景。我是 JavaScript 和 TypeScript 的新手。

Here is my array:

这是我的数组:

        var data = [
        { time: '9:54' }, 
        { time: '9:54' },
        { time: '9:54' },
        { time: '9:55' }, 
        { time: '9:55' },
        { time: '9:55' },
        { time: '9:55' },
        { time: '9:56' }, 
        { time: '9:56' },
        { time: '9:56' },
        { time: '9:56' },
        { time: '9:57' }, 
        { time: '9:57' },
        { time: '9:57' },
        { time: '9:57' },
        { time: '9:57' }
    ];

This is how I need my array for use in a rechart graph:

这就是我需要在重新图表中使用我的数组的方式:

        var dataWithCounts = [
        { time: '9:54', messages: 3 }, 
        { time: '9:55', messages: 4 }, 
        { time: '9:56', messages: 4 }, 
        { time: '9:57', messages: 5 }
    ];

With the help of 'Just a Student's' answer from this Stack Overflow question: Group and count values in an array , I have the following.

在这个堆栈溢出问题的“只是一个学生”的回答的帮助下:Group and count values in an array ,我有以下内容。

        var counts = data.reduce((newArray, item) => {
           let time = item.time;
           if (!newArray.hasOwnProperty(time)) {
               newArray[time] = 0;
           } 
           newArray[time]++;
           return newArray;
        }, {});

        console.log(counts);

        var countsExtended = Object.keys(counts).map(k => {
           return { time: k, messages: counts[k] };
       });

       console.log(countsExtended);

Where and how do I declare an index signature? Below are various things I've tried.

我在哪里以及如何声明索引签名?以下是我尝试过的各种事情。

  • let newArray: { [time: string] };and receive a duplicate identifier error.

  • adding string to the parameter var counts = data.reduce((newA:string, item)gives me an error "Element implicitly has an 'any' type because index expression is not of type 'number'."

  • adding newA[time].toString()gives me errors, "The left-hand side of an assignment expression must be a variable or a property access."

  • let newArray: { [time: string] };并收到重复的标识符错误。

  • 向参数添加字符串var counts = data.reduce((newA:string, item)会给我一个错误“元素隐式具有 'any' 类型,因为索引表达式不是 'number' 类型。”

  • 添加newA[time].toString()给我错误,“赋值表达式的左侧必须是变量或属性访问。”

回答by CRice

The type of your accumulator in the .reducecall is almost certainly the issue. Since it is just given as {}, that's what its type is inferred as, and the type {}doesn't have an index signature. You can fix this by casting your initial value so that it does include a signature:

.reduce调用中累加器的类型几乎肯定是问题所在。由于它只是作为 给出{},这就是它的类型被推断为的,并且该类型{}没有索引签名。您可以通过转换初始值来解决此问题,以便它确实包含签名:

var counts = data.reduce((newArray, item) => {
    let time = item.time;
    if (!newArray.hasOwnProperty(time)) {
        newArray[time] = 0;
    } 
    newArray[time]++;
    return newArray;
}, {} as {[key: string]: any}); // <-- note the cast here

I gave the index signature type any, but you may want to make it something more specific for your particular case.

我给出了索引签名类型any,但您可能希望针对您的特定情况使其更具体。

回答by Jonas Wilms

The correct types for your array would be:

数组的正确类型是:

Array<{time: string}>

or:

或者:

{time: string}[]

or:

或者:

{[key: number]: {time: string}}

回答by I wrestled a bear once.

If I'm understanding you, you need to create the interface for the object...

如果我理解你,你需要为对象创建接口......

interface counts_t{
    time?: string,
    messages?: number
}

var data: counts_t[] = [
    { time: '9:54' }, 
    { time: '9:55' }, 
    { time: '9:56' }, 
    { time: '9:57' }
];

    var counts = data.reduce((newArray:counts_t, item:counts_t) => {
       let time = item.time;
       if (!newArray.hasOwnProperty(time)) {
           newArray[time] = 0;
       } 
       newArray[time]++;
       return newArray;
    }, {});

    console.log(counts);

    var countsExtended: counts_t[] = Object.keys(counts).map(k => {
       return { time: k, messages: counts[k] };
    });

   console.log(countsExtended);