![](/img/trans.png)
[英]Unsafe use of expression of type 'any' for return statements in Typescript function
[英]TypeScript Unsafe use of expression of type 'any' ERROR
我是 TypeScript 的新手,並將我的場景描述如下:
我有這樣的類型:
type response = {
totalQuantity: number;
numberOfCatogory: number
appleQuantity: number;
bananaQuantity: number;
pearQuantity: number;
};
每個單獨的水果數量都有驗證,在這種情況下是 appleQuantity、bananaQuantity 和 pearQuantity,這意味着我需要從響應中獲取每個單獨的水果數量。
所以我創建了一個字符串數組,它像這樣保存單個屬性鍵:
const individualParameters: string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"]
Function 邏輯如下:
for (const individualParameter of individualParameters) {
let individualQuantity = response[individualParameter];
...
}
但是當我構建時,TSLint 在response[individualParameter]
上拋出錯誤說
Unsafe use of expression of type 'any'
我認為這是因為響應無法識別字符串數組元素的類型?
我是 TypeScript 的新手,很好奇解決這個問題的好方法。
問題出在這一行: const individualParameters:string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"]
。
根據individualParameters
的類型定義,每個元素都是一個string
。 這意味着即使這個"foo"
字符串也可以分配給類型string
。
因此,typescript 拒絕使用response[individualParameter]
因為response
是具有嚴格鍵的類型,而individualParameter
可能是任何字符串。
為了使其工作,您可以使用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
}
如果您不喜歡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
Obj
- 表示response
參數, Keys
- 確保第二個數組參數由有效的Obj
鍵組成
PS 根據 TS 約定,類型應該大寫。
所以我認為大多數人已經解釋了發生了什么,我認為到目前為止我個人最喜歡的答案是船長-yossarian 的答案。 他很好地解釋了這個問題:
因此,typescript 拒絕使用 response[individualParameter] 因為 response 是具有嚴格鍵的類型,而 individualParameter 可能是任何字符串。
但是,可以通過告訴 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];
}
類型(keyof response)[]
意味着您將始終擁有一個僅包含response
類型鍵的數組。 在我的示例中,此聲明是多余的,因為編譯器已經可以推斷出您定義的所有屬性都是該類型的鍵,但是當 for 循環位於 function 中時,情況就不同了。 我假設你就是這種情況,否則你不會在第一種情況下問這個問題。
@captain-yossarian 是對的; 根據 TS 約定,類型應該大寫。
您需要使您的響應可索引。 更多信息可以在這里找到。
在您的情況下,可以通過使用如下接口來完成:
interface IResponse {
[key: string]: number; // <- This line makes your interface indexable
totalQuantity: number;
numberOfCatogory: number
appleQuantity: number;
bananaQuantity: number;
pearQuantity: number;
}
現在你只需要確保你的響應實現了 IResponse 接口:
const response: IResponse = {
totalQuantity: 1,
numberOfCatogory: 2,
appleQuantity: 3,
bananaQuantity: 4,
pearQuantity: 5
}
在此之后,您可以使用字符串數組來獲取單個水果數量,如下所示:
const individualParameters: string[] = ["appleQuantity", "bananaQuantity", "pearQuantity"];
for (let individualParameter of individualParameters) {
console.log(response[individualParameter]);
}
// Output:
// 3
// 4
// 5
一種簡單的方法是您可以選擇將類型的鍵設為字符串變量
type response = {
[key: string]: number;
};
但是,如果您真的要修復 key 為 appleQuantity、 bananaQuantity 、blablabla,您可以嘗試Mapped Type ,點擊此鏈接了解更多詳情
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.