繁体   English   中英

Typescript:如何将 map 字符串类型转化为具有许多不同子类型的泛型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM