简体   繁体   English

TypeScript 不安全地使用“任何”类型的表达式错误

[英]TypeScript Unsafe use of expression of type 'any' ERROR

I am new to TypeScript and describe my scenario as follow:我是 TypeScript 的新手,并将我的场景描述如下:

I have a type like this:我有这样的类型:

 type response = {
  totalQuantity: number;
  numberOfCatogory: number
  appleQuantity: number;
  bananaQuantity: number;
  pearQuantity: number;
};

There is validation on each individual fruit quantity, in this case are appleQuantity, bananaQuantity, and pearQuantity, which means I need to get each individual fruit quantity from response.每个单独的水果数量都有验证,在这种情况下是 appleQuantity、bananaQuantity 和 pearQuantity,这意味着我需要从响应中获取每个单独的水果数量。

So I created a string array which saves individual property key like this:所以我创建了一个字符串数组,它像这样保存单个属性键:
const individualParameters: string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"]

Function logic like this: Function 逻辑如下:

for (const individualParameter of individualParameters) {
    let individualQuantity = response[individualParameter];
    ...
}

But when I build, TSLint throws error at response[individualParameter] saying但是当我构建时,TSLint 在response[individualParameter]上抛出错误说

Unsafe use of expression of type 'any'

I think it is because response can't recognize type from string array element?我认为这是因为响应无法识别字符串数组元素的类型?
I am new to TypeScript and curious of a good way to solve this problem.我是 TypeScript 的新手,很好奇解决这个问题的好方法。

Problem is in this line: const individualParameters:string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"] .问题出在这一行: const individualParameters:string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"]

According to type definition of individualParameters each element is a string .根据individualParameters的类型定义,每个元素都是一个string It means that even this "foo" string is assignable to type string .这意味着即使这个"foo"字符串也可以分配给类型string

Hence, typescript rejects using response[individualParameter] because response is a type with strict keys whereas individualParameter might be any string.因此,typescript 拒绝使用response[individualParameter]因为response是具有严格键的类型,而individualParameter可能是任何字符串。

In order to make it work, you can use const assertion :为了使其工作,您可以使用const assertion

type response = {
  totalQuantity: number;
  numberOfCatogory: number
  appleQuantity: number;
  bananaQuantity: number;
  pearQuantity: number;
};

const individualParameters = ["appleQuantity", "bananaQuantity", "pearQuantity"] as const

declare const response: response;

for (const individualParameter of individualParameters) {
  let individualQuantity = response[individualParameter]; // ok

}

If you don't like as const approach, you can use extra function:如果您不喜欢as const方法,可以使用额外的 function:

type response = {
  totalQuantity: number;
  numberOfCatogory: number
  appleQuantity: number;
  bananaQuantity: number;
  pearQuantity: number;
};


declare const response: response;

const iterator = <
  Obj extends Record<string, number>,
  Keys extends Array<keyof Obj>
>(record: Obj, keys: Keys) => {
  for (const individualParameter of keys) {
    let individualQuantity = record[individualParameter];
  }
}

iterator(response, ['foo']) // expected error

// works only with literal array
iterator(response, ["appleQuantity", "bananaQuantity", "pearQuantity"]) // ok

Playground操场

Obj - represents response argument, Keys - makes sure that second array argument consists of valid Obj keys Obj - 表示response参数, Keys - 确保第二个数组参数由有效的Obj键组成

PS According to TS convention, types should be capitalized. PS 根据 TS 约定,类型应该大写。

So I think most people already explained what's going on and I think my personal favourite answer thus far is captain-yossarian's answer .所以我认为大多数人已经解释了发生了什么,我认为到目前为止我个人最喜欢的答案是船长-yossarian 的答案 He explained the problem very well:他很好地解释了这个问题:

Hence, typescript rejects using response[individualParameter] because response is a type with strict keys whereas individualParameter might be any string.因此,typescript 拒绝使用 response[individualParameter] 因为 response 是具有严格键的类型,而 individualParameter 可能是任何字符串。

This issue, however, can easily be resolved by telling Typescript that you're defining an array containing strings that are also keys of the type you're trying to access:但是,可以通过告诉 Typescript 您正在定义一个包含字符串的数组来轻松解决此问题,这些字符串也是您尝试访问的类型的键:

type response = {
  totalQuantity: number;
  numberOfCatogory: number
  appleQuantity: number;
  bananaQuantity: number;
  pearQuantity: number;
};

// this should be your non-null and defined object in reality
let response: response;

// just this one line below was altered
const individualParameters: (keyof response)[] = ["appleQuantity", "bananaQuantity", "pearQuantity"];

for (const individualParameter of individualParameters) {
    let individualQuantity = response[individualParameter];
}

The type (keyof response)[] means you'll always have an array with just the keys of a response type.类型(keyof response)[]意味着您将始终拥有一个仅包含response类型键的数组。 In my example this declaration is redundant as the compiler can already infer that all properties you defined are keys of the type, but this is a different story when the for loop is in a function, for instance.在我的示例中,此声明是多余的,因为编译器已经可以推断出您定义的所有属性都是该类型的键,但是当 for 循环位于 function 中时,情况就不同了。 I assume this is the case for you, otherwise you wouldn't be asking this question in the first case.我假设你就是这种情况,否则你不会在第一种情况下问这个问题。

And @captain-yossarian is right; @captain-yossarian 是对的; According to TS convention, types should be capitalised.根据 TS 约定,类型应该大写。

You need to make your response indexable.您需要使您的响应可索引。 More information about that can be found here .更多信息可以在这里找到。

In your case it can be done by using an Interface like so:在您的情况下,可以通过使用如下接口来完成:

interface IResponse {
  [key: string]: number;  // <- This line makes your interface indexable
  totalQuantity: number;
  numberOfCatogory: number
  appleQuantity: number;
  bananaQuantity: number;
  pearQuantity: number;
}

Now you just need to make sure your response implements the IResponse interface:现在你只需要确保你的响应实现了 IResponse 接口:

const response: IResponse = {
  totalQuantity: 1,
  numberOfCatogory: 2,
  appleQuantity: 3,
  bananaQuantity: 4,
  pearQuantity: 5
}

After this you are able to use your string array for getting individual fruit quantities like so:在此之后,您可以使用字符串数组来获取单个水果数量,如下所示:

const individualParameters: string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"];

for (let individualParameter of individualParameters) {
    console.log(response[individualParameter]);
}

// Output:
// 3
// 4
// 5

One simple way is that you can choose to make your type's key as string variable一种简单的方法是您可以选择将类型的键设为字符串变量

type response  = {
    [key: string]: number;
};

But if you really to be fix key to be appleQuantity, bananaQuantity, blablabla you can try out Mapped Type , click this link for more details https://www.typescriptlang.org/docs/handbook/2/mapped-types.html但是,如果您真的要修复 key 为 appleQuantity、 bananaQuantity 、blablabla,您可以尝试Mapped Type ,点击此链接了解更多详情

暂无
暂无

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

相关问题 对 Typescript function 中的 return 语句不安全地使用“any”类型的表达式 - Unsafe use of expression of type 'any' for return statements in Typescript function Typescript - eslint 错误分配给类型的“任何”类型的不安全参数 - Typescript - eslint error Unsafe argument of type 'any' assigned to a type 在 header object 上不安全地使用表达式 any - Unsafe use of expression any on header object 任何值 ESLint 错误的 Typescript 不安全分配 - Typescript Unsafe Assignment of An Any Value ESLint Error 在打字稿中使用reduce,错误“元素隐式具有&#39;任何&#39;类型,因为类型的表达式不能用于索引类型&#39;{}&#39;” - use reduce in typescript, Error "element implicitly has an 'any' type because expression of type can't be used to index type '{}'" TypeScript 错误元素隐式具有“任何”类型,因为“任何”类型的表达式不能用于索引类型 - TypeScript error Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 收到此打字稿错误:对任何值不安全的成员访问 [key] - Getting this typescript error: Unsafe member access [key] on an any value Typescript 数组 Map 的对象不产生任何不安全的任何错误 - Typescript Array Map of Objects Producing No Unsafe Any Error Typescript 错误:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型 - Typescript Error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type TypeScript 错误:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{}” - TypeScript Error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM