![](/img/trans.png)
[英]Typescript: Generic Constraint Could Be Insantiated With Different Subtypes
[英]Typescript: How to map string type to generic with many different subtypes
我正在尝试在本地存储之上创建一个类型化接口,我可以仅使用字符串键以类型化方式从本地存储设置/获取。 我想要将字符串类型映射到 generics,这样我就可以进行自定义序列化/反序列化。
我遇到的问题是,当我使用从字符串类型到 object 泛型的映射 object 到 go 时,Typescript 似乎无法正确推断类型。 如果有人对 go 的最佳方式有一些好的建议,那就太好了! ❤️
我在下面有一个例子可以更好地解释我的情况:
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");
您可以通过向 function 添加泛型类型参数来捕获传入的key
的实际类型,从而使x
成为boolean
但是,您仍然需要在实现中进行一些类型断言,因为 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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.