TypeScript - ts(7053) : Element implicitly has an 'any' type because expression of type 'string' can't be used to index

后端 未结 2 1456
予麋鹿
予麋鹿 2021-01-17 05:24

In TypeScript, I declare an interface like this:

export default interface MyDTO {
    readonly num: string;
    readonly entitle: string;
    readonly trb: st         


        
相关标签:
2条回答
  • 2021-01-17 05:57

    @mhodges, with your suggestions, here is my modified function which seems to work well. However in the following case, I had to add the "as string" otherwise I have the following error:

    Type 'string | keyof V 'cannot be used to index type' V'.ts (2536)

    public getDefaultComparator(property: keyof V | string, v1: V, v2: V): number {
        let compareReturn = 0;
        if (v1.hasOwnProperty(property)) {
          const compareValue1 = v1[property as string];
          const compareValue2 = v2[property as string];
          if (compareValue1 > compareValue2) {
            compareReturn = 1;
          } else if (compareValue1 < compareValue2) {
            compareReturn = -1;
          }
        }
    
        return compareReturn;
      }
    
    0 讨论(0)
  • 2021-01-17 06:14

    The reason for this is because MyDTO has explicitly named properties, but you're using a generic string as an index, so TypeScript is saying that it can't guarantee that whatever string is passed into your doSomething function will actually match a property name on your interface.

    An excellent workaround for this that was introduced in TypeScript 2.1 is keyof. This allows you to explicitly type something as a key of a certain class/interface.

    This will A. get rid of the TS error you're seeing, and B. also check to make sure that any callers of your function actually pass a valid key.

    export default interface MyDTO {
        readonly num: string;
        readonly entitle: string;
        readonly trb: string;
        readonly ucr: string;
        readonly dcr: string;
        readonly udm?: string;
        readonly ddm?: string;
    }
    
    function doSomething(dto: MyDTO, property: keyof MyDTO): any {
        let label: any;
    
        if (['dcr', 'ddm'].includes(property)) {
            label = doSomethingElse(dto[property]);
        } else {
            label = dto[property];
        }
        
        return label;
    }
    
    doSomething(obj, "foo") // is a TS error
    doSomething(obj, "num") // is valid
    
    0 讨论(0)
提交回复
热议问题