获取本地 JSON 数据:元素隐含类型为“any”

Posted

技术标签:

【中文标题】获取本地 JSON 数据:元素隐含类型为“any”【英文标题】:Get local JSON data: The element has a type "any" implicitly 【发布时间】:2021-12-25 16:28:03 【问题描述】:

我有一个带有 Typescript 的 Node JS 项目,我在其中创建一个 API 以根据给定的变量从本地 JSON 文件获取数据。

这是我的model.ts

interface ListProductBatchModel 
    resp: ResultMsg


interface ResultMsg 
    name?: string,
    price?: string,
    error?: string


export  ListProductBatchModel, ResultMsg ;

这是我的properties JSON 文件:


    "CT": 
        "name": "box",
        "price": "5,00"
    ,
    "CC": 
        "name": "car",
        "price": "6,00"
    

这是我的controller.ts

import * as logger from 'winston';
import  Controller, Get, Response, Route, SuccessResponse, Tags  from 'tsoa';

import  ListProductBatchModel  from './models/listProduct.models';
import  ListProductBatchUtils  from './utils/listProductBatch.utils';

@Route('/list/product')
@Tags('list-product')

export class ListProductBatchController 

    private listProductBatchUtils: ListProductBatchUtils;

    constructor() 
        this.listProductBatchUtils = new ListProductBatchUtils();
    

    @Get('/codProduct')
    @SuccessResponse(200, 'Success Response')
    async listProductBatch(codProduct: string): Promise<ListProductBatchModel> 
        try 
            const listProductBatch = await this.listProductBatchUtils.getDataProduct(codProduct);
            return Promise.resolve(listProductBatch as ListProductBatchModel);
         catch (error) 
            logger.info(JSON.stringify(error));
            return Promise.reject(error);
        
    

这是我的utils.ts

import * as logger from 'winston';
import * as getProperty from '../json/product.json';
import  ListProductBatchModel, ResultMsg  from '../models/listProduct.models';

export class ListProductBatchUtils 

    public async getDataProduct(codProduct: string): Promise<ListProductBatchModel> 

        try 

            let result: ResultMsg;
            if (getProperty[codProduct.toUpperCase()]) 
                result = 
                    name: getProperty[codProduct.toUpperCase()].name,
                    price: getProperty[codProduct.toUpperCase()].price
                

            else 
                result = 
                    error: "ERROR"
                
            
            logger.info('start')
            return Promise.resolve( resp: result );
            
         catch (error) 
            logger.info(JSON.stringify(error));
            return Promise.reject(error);
        
    

这是我在getProperty [codProduct.toUpperCase ()] 中遇到的错误:

The element has a type "any" implicitly because the expression of type "string" cannot be used to index the type "CT: name: string; price: string;; CC: name: string; price : string;; ".
   No index signature was found with a parameter of type "string" in type "CT: name: string; price: string;; CC: name: string; price: string;;".

我的问题:我不明白错误是如何产生的,我想要的是取与 codProduct 变量匹配的名称和价格属性。为什么会发生这种情况?我做错了什么,我该如何解决?

【问题讨论】:

【参考方案1】:

现在,codProductstring。当您通过其下标[] 访问getProduct 时,TypeScript 期望您使用getProduct 的索引(在本例中为"CT""CC")。

您可以通过将 string 转换为 keyof getProperty 的类型来满足 TypeScript 编译器的要求。请注意,这将在编译时起作用,但不会保证它实际上是 getProperty 在运行时的键。但是,由于您已经在进行布尔检查,因此在您的情况下似乎没问题。

这是一个简化的例子:

const getProperty = 
    "CT": 
        "name": "box",
        "price": "5,00"
    ,
    "CC": 
        "name": "car",
        "price": "6,00"
    
;

type GetPropertyType = typeof getProperty;

function myFunc(input: string) 
    const result = getProperty[input.toUpperCase() as keyof GetPropertyType].name;

【讨论】:

我不明白为什么会这样,我唯一想要的是获得与获得的变量匹配的属性,我不知道我必须这样做。每次我想从属性中获取一些数据时,有没有办法避免这样做?是否可以只执行一次以影响所有 getProperties? 这是因为string 是比getProperty 的键更宽的类型。例如,您的input 可以是“Hello, World!”。如果您想避免在函数内部进行强制转换,我的建议是将您的函数签名更改为仅接受 keyof GetPropertyType 而不是 string。然后,您将在该函数的调用站点进行强制转换。或者,更改您的 API,以便您不处理 string 而只处理有效密钥。

以上是关于获取本地 JSON 数据:元素隐含类型为“any”的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript - ReactRouter |箭头函数捕获隐含类型为“any”的“this”的全局值

Node + TypeScript:“this”隐含类型“any”

mongoose virtuals with typescript error - 包含箭头函数捕获“this”的全局值,该值隐含类型为“any”

参数 'e' 隐含了一个 'any' 类型 React TypeScript

TypeScript Err:“元素隐式具有‘any’类型,因为‘any’类型的表达式不能用于索引类型

元素隐含地具有“任何”类型,因为类型“AbstractControl”没有索引签名。您的意思是调用“get”吗?ngtsc(7052)