我正在尝试使用 TypeScript 将使用字符串类型的代码库的一部分转换为类似枚举的类型。问题是在某些地方字符串值略有不同。有没有办法创建一个类型,其中多个值与同一个键匹配,而不是创建两个几乎相同的类似枚举的类型?
我的尝试看起来像这样(不起作用):
const STATUS = {
CREATED: "CREATED",
PICKED_UP: "PICKED UP" | "PICKED_UP",
DELIVERED: "DELIVERED" | "DEL"
} as const
type ObjectValues<T> = T[keyof T];
type Status = ObjectValues<typeof STATUS>;
我正在寻找一个可以做到这一点的解决方案:
console.log(STATUS.PICKED_UP === "PICKED UP" && STATUS.PICKED_UP === "PICKED_UP") //should be true
doThingWithStatus("PICKED_UP") //should be ok, assuming function expects a type Status input
谢谢大家!
如上所述,不,不可能按照您的要求进行操作。当然,当 STATUS.PICKED_UP === "PICKED UP"
为
false时,你不可能让
STATUS.PICKED_UP === "PICKED_UP"
都为 true 且 "PICKED UP" === "PICKED_UP"
为 true。 STATUS.PICKED_UP
是某个值,该值可以是这些字符串中的一个,也可以不是其中一个,但不能是这些字符串中的both。 (这可能就是为什么你在编写像
"PICKED UP" | "PICKED_UP"
这样的 value时遇到困难。无论如何,这是按位 OR 运算符,并且不会作用于字符串。而且没有运算符可以将两个字符串组合成一个字符串不知何故等于它们的both的字符串。)
STATUS
的成员映射到字符串的collections 。例如,您可以使用数组,如
const STATUS = {
CREATED: ["CREATED"],
PICKED_UP: ["PICKED UP", "PICKED_UP"],
DELIVERED: ["DELIVERED", "DEL"]
} as const;
那么 Status
就是
ObjectValues<typeof STATUS>
的 elements 的 union:
type Status = ObjectValues<typeof STATUS>[number];
// type Status = "CREATED" | "PICKED UP" | "PICKED_UP" | "DELIVERED" | "DEL"
您的检查将是 STATUS
includes
的成员是否是其集合中的字符串之一:
console.log(
STATUS.PICKED_UP.includes("PICKED UP") &&
STATUS.PICKED_UP.includes("PICKED_UP")
); // true
STATUS
对象,以便切换键和值,因为对象允许具有不同keys 的属性具有相同的 value,但反之则不然(我没有看到您建议例如,
"DEL"
出现在
STATUS.DELIVERED
和
STATUS.DELETED
中,大概您考虑的是多对一或一对多关系,而不是多对多):
const STATUS_REV = {
CREATED: "CREATED",
PICKED_UP: "PICKED_UP",
"PICKED UP": "PICKED_UP",
DELIVERED: "DELIVERED",
DEL: "DELIVERED"
} as const
那么 Status
就是
STATUS_REV
的 keys的并集
type Status = keyof typeof STATUS_REV;
// type Status = "CREATED" | "PICKED UP" | "PICKED_UP" | "DELIVERED" | "DEL"
您的检查将是前一个键是否是 "PICKED UP"
的 value
或
"PICKED_UP"
的
STATUS_REV
属性:
console.log(
"PICKED_UP" === STATUS_REV["PICKED UP"] &&
"PICKED_UP" === STATUS_REV["PICKED_UP"]
); // true