我正在嘗試在本地存盤之上創建一個型別化的介面,我可以只使用字串鍵以型別化的方式從本地存盤中設定/獲取。我希望將字串型別映射到泛型,從而允許我進行自定義序列化/反序列化。
我遇到的問題是,當我使用映射物件從字串型別轉到物件泛型時,Typescript 似乎無法正確推斷型別。如果有人對解決此問題的最佳方法有一些好的建議,那就太棒了!??
我在下面有一個例子可以更好地解釋我的情況:
type LocalStorageKey = "bool_test" | "num_test";
type LocalStorageKeyInfo<T> = {
key: LocalStorageKey;
getDefault(): T;
serialize(val: T): string;
deserialize(lsVal: string | null, defaultVal: T): T;
};
const BooleanSerializer = (val: boolean) => String(val);
const BooleanDeserializer = (lsVal: string | null, defaultVal: boolean) => {
if (lsVal === null) {
return defaultVal;
} else {
return lsVal === "true";
}
};
const NumberSerializer = (val: number) => String(val);
const NumberDeserializer = (lsVal: string | null, defaultVal: number) => {
if (lsVal === null) {
return defaultVal;
} else {
return Number(lsVal);
}
};
export const BoolTestKeyInfo: LocalStorageKeyInfo<boolean> = {
key: "bool_test",
getDefault: () => false,
serialize: BooleanSerializer,
deserialize: BooleanDeserializer,
};
export const NumTestKeyInfo: LocalStorageKeyInfo<number> = {
key: "num_test",
getDefault: () => 0,
serialize: NumberSerializer,
deserialize: NumberDeserializer,
};
const keyInfoMapping = {
bool_test: BoolTestKeyInfo,
num_test: NumTestKeyInfo,
};
export function getKeyVal(key: LocalStorageKey) {
const keyInfo = keyInfoMapping[key];
try {
return keyInfo.deserialize(
window.localStorage.getItem(keyInfo.key),
// This line is the issue because deserialize's second arg is infered as never
keyInfo.getDefault()
);
} catch (e) {
return keyInfo.getDefault();
}
}
// I want x to be a boolean here
const x = getKeyVal("bool_test");
uj5u.com熱心網友回復:
您可以通過x向boolean函式添加泛型型別引數來捕獲key傳入的實際型別。但是,您仍然需要在實作中進行一些型別斷言,因為 ts 不能很好地遵循變數之間的相關性。
export function getKeyVal<K extends LocalStorageKey>(key: K) :ReturnType<typeof keyInfoMapping[K]['getDefault']>
export function getKeyVal(key: LocalStorageKey) {
const keyInfo = keyInfoMapping[key];
try {
return keyInfo.deserialize(
window.localStorage.getItem(keyInfo.key),
// This line is the issue because deserialize's second arg is infered as never
keyInfo.getDefault() as never
);
} catch (e) {
return keyInfo.getDefault();
}
}
游樂場鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/430696.html
上一篇:創建泛型類引數的實體
