[英]Is it possible to detect type of generic in TypeScript?
我正在嘗試使用 generics 以便調用者可以定義他們預測得到的類型。
我的代碼是這樣的:
const getStoredData = async <T extends string | object>(key: typeof localStorageKeys[number]): Promise<T | null> => {
try {
// value is always returned as string
const value = await AsyncStorage.getItem(key);
if (value === null) return null;
// I want to create condition to check if T is string or not
// if T is object type then return parsed JSON, otherwise just string
return value != null ? JSON.parse(value) : null;
} catch (e) {
return null;
}
};
// I wanna achieve like below using the function above
// storedValue should be string
const storedValue = await getStoredValue<string>('someKey');
// then storedObjValue should be MyCustomType type
const storedObjValue = await getStoredValue<MyCustomType>('some_key');
有誰知道如何實現這一目標?
我會使用try/catch 塊
let returnValue;
try {
returnValue = JSON.parse(value);
} catch(e) {
returnValue = value;
}
如果JSON.parse
失敗,它會將其設置為字符串值。
您可以使用typeof
typeof value === 'string' ? value : JSON.parse(value)
為了回答這些問題,我想到了 ts 編譯器如何在運行代碼之前知道這些數據。 如果項目已經從類型定義中獲得了該數據,那么您可以從中推斷出它,但如果數據是通過請求來自外部源,則 ts 編譯器無法推斷出它將是什么。
但是您仍然可以做一些事情,那就是創建您自己的 AsyncStorage 期望定義。 所以我建議你創建一個接口來定義鍵和預期的結果。
interface DataSource {
someKey: number;
some_key: string;
Some_Key: Record<string, number>;
}
const dataSource: DataSource = {
someKey: 1,
some_key: "a",
Some_Key: {
value: 2,
},
};
interface AsyncStorage {
get: <T extends keyof DataSource>(key: T) => DataSource[T];
}
const storage: AsyncStorage = {
get: (key) => dataSource[key],
};
const key1 = storage.get("someKey"); // string
const key2 = storage.get("some_key"); // number
const key3 = storage.get("Some_Key"); // Record<string, number>
聽取@Gonzalo 的建議,我按照下面的方式進行操作,並且似乎有效。
type LocalStorageType = {
user_id: string;
user_something: UserSomethingType;
};
type LocalStorageKeys = keyof LocalStorageType;
type LocalStorageValue = LocalStorageType[LocalStorageKeys];
const getStoredData = async <T extends LocalStorageValue>(
key: LocalStorageKeys,
): Promise<T | null> => {
try {
const value = await AsyncStorage.getItem(key);
if (value === null) return null;
if (key === 'user_id') return value as T;
return JSON.parse(value) as T;
} catch (e) {
return null;
}
};
這可能不是最佳的,因為 LocalStorageType 中可能的字符串值可能會增加很多if
如下所示。
type LocalStorageType = {
user_id: string;
user_name: string;
user_email: string;
user_something: UserSomethingType;
some_value: CustomType;
some_value_two: CustomOneType;
};
// now I have to make at least 3 conditions(user_id, user_name, user_email) to distinguish string or custom types
如果有人知道如何防止這種情況,請告訴我!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.