English 中文(简体)
类型——在类型定义中如何获得大类的价值
原标题:Typescript - How to get the value of enum type in type definition
  • 时间:2023-08-01 01:09:53
  •  标签:
  • typescript

我试图根据um的价值确定一种类型。

enum E {
    A = "apple",
    B = "banana",
    C = "cherries"
}

// type EnumKey = "A" | "B" | "C"
type EnumKey = keyof typeof E

/**
 * Error:
 * Property  A  does not exist on type  E .
 * Property  B  does not exist on type  E .
 * Property  C  does not exist on type  E .
 */
type EnumValue = E[EnumKey]

// type EnumValue2 = E
type EnumValue2 = (typeof E)[EnumKey]

type EnumValueExpected = "apple" | "banana" | "cherries"

在产出分类中,这些特性在<代码>上确实存在。 E:

"use strict";
var E;
(function (E) {
    E["A"] = "apple";
    E["B"] = "banana";
    E["C"] = "cherries";
})(E || (E = {}));

我不理解为什么会有一些错误,我如何获得<条码>。 EnumValueExpected ?

问题回答

鉴于enum

enum E {
    A = "apple",
    B = "banana",
    C = "cherries"
}

您的原始版本主要因为您是。 (其类型为<编码>E,而不是 E。) 见


重新研究的类型非常接近。 E union union <>E 具体来说,作为字面类型的特殊subtype处理,因此,你可以仅作书面处理,例如,>cherries> inplace of E.C

In some sense, the whole point of an enum is to abstract away the actual literal types of the values. If you actually care about these literal types, you might want to avoid enum entirely in favor of an object of the same shape:

const EObject = {
  A: "apple",
  B: "banana",
  c: "cherries"
} as const;

type EKey = keyof typeof EObject;
// type EKey = "A" | "B" | "c"
type EValue = (typeof EObject)[EKey];
// type EValue = "apple" | "banana" | "cherries"

as const 请汇编者跟踪标值的字面值的描述,以便你能够轻易地提取钥匙和价值类型。

但是,也许你的使用情况不允许这样做。


If you really want to extract "apple" | "banana" | "cherries" from E, you can use template literal types to ask "what happens when I serialize E as a string"?

enum E {
  A = "apple",
  B = "banana",
  C = "cherries"
}

type EValue = `${E}`;
// type EValue = "apple" | "banana" | "cherries"

这产生了理想的结合。 请注意,如果<条码>E> 是全数<>。 最后,请附上数字的缩略语。

enum F {
  D = "durian",
  E = 123,
  F = "figs",
  G = 456
}
type FValueOops = `${F}`
// type FValueOops = "durian" | "figs" | "123" | "456"

If such things matter you could more effort teasing numeric and string literals out:

type EnumToLiteral<T extends string | number> =
  T extends string ? `${T}` : `${T}` extends `${infer N extends number}` ? N : never;

type FValue = EnumToLiteral<F>;
// type FValue = "durian" | 123 | "figs" | 456

但是,在进行这种分类之前,我建议采用<条码>作为星号/代码>而不是<条码>。

Playground link to code





相关问题
store data in memory with nestjs

I am trying to persist some data in my nestjs server so I can then use that data in my client app through http requests. I have created a products.service.ts file with the function getAllData() that ...

React Hook Form Error on custom Input component

I am having a problem when I use react hook form + zod in my application, in short the inputs never change value and I get the following error in the console: Warning: Function components cannot be ...

Updatable promises using proxy in JavaScript

EDIT: I ve updated this question, and the old question is moved here. A POC can be found on this jsfiddle or the snippet below GOAL: The goal here is to make or rather simulate a promise that can be ...