[英]Using the keys of an object literal as a Typescript type?
我有一個對象,其中包含我的應用程序的一些預定義數據,它存儲在一個常量變量中,如下所示:
const data:{[key:string]:any} =Object.freeze({
some: 123,
long: {"a":"b"},
list: ["c"],
of: "",
arbitrary: null,
things: 1.2,
});
該對象的鍵對於應用程序的其余部分是已知的。 考慮這個訪問數據對象的函數:
function doWork(k) {
if(!data.hasOwnProperty(k)) throw Error();
let value = data[k];
//...
}
這被稱為字符串
doWork("things");
我想用 Typescript 編譯時檢查替換無效鍵的運行時錯誤。 我希望能夠寫
function doWork(k: keyof data) {
let value = data[k];
//...
}
但顯然keyof
運算符不能那樣工作。 我收到錯誤TS2304: Cannot find name 'data'.
我的解決方法:我可以用這樣的東西提取對象的鍵:
console.log("\""+Object.keys(data).join("\"|\"")+"\"");
然后我可以復制/粘貼並定義為類型。
type data_key = "some"|"long"|"list"|"of"|"arbitrary"|"things"
export function doWork(k:data_key) {
let value = data[k];
//...
}
這感覺就像一個愚蠢的 hack 並且每當我必須進行更改時都非常不方便,因為我必須記住將此語句放在正確的位置,運行程序,然后手動將值復制回源代碼(或實際上,只需自己輸入更改即可)。
我對更好的解決方案持開放態度。 是否有提供我正在尋找的功能的語言功能?
讓 TypeScript 推斷data
的類型,然后使用type data_key = keyof typeof data;
從它推斷的類型中提取鍵type data_key = keyof typeof data;
:
const data = Object.freeze({
some: 123,
long: {"a":"b"},
list: ["c"],
of: "",
arbitrary: null,
things: 1.2,
});
type data_key = keyof typeof data;
function doWork(k: data_key) {
let value = data[k];
//...
}
它是如何工作的:
Object.freeze
的對象初始值設定項的類型,鍵為some
、 long
、 list
等。 Object.freeze
被定義為freeze<T>(o: T): Readonly<T>
¹ 所以它返回相同推斷類型的Readonly
版本。keyof
獲取類型的鍵。typeof
在這個上下文中是 TypeScript 的typeof
,而不是 JavaScript 的。 在 TypeScript 中,有些地方需要運行時值,有些地方需要編譯時類型。 keyof
的操作數是需要編譯時類型的地方,因此typeof data
返回編譯時類型的data
,這是從freeze
推斷類型的只讀版本(鍵為some
、 long
、 list
等.) (如果您有x = typeof data
,那么在需要運行時值的上下文中將是typeof
,因此它將是 JavaScript 的typeof
,而x
將獲得運行時值"object"
。) ¹ lib.es5.d.ts
中實際上有三種freeze
定義(一種用於數組,一種用於函數,一種用於所有其他類型的對象;這是最后一種)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.