TypeScript:有没有办法对 Object.values 返回的数组进行 const 断言?

Joj*_*oji 5 javascript typescript

这是现场演示:https://codesandbox.io/s/vigorous-rgb-u860z ?file=/src/index.ts

enum Keys {
  One = "one",
  Two = "two"
}

const a = Object.values(Keys).map((value, index) => ({
  label: value,
  id: String(index)
})) as const;

Run Code Online (Sandbox Code Playgroud)

这是错误消息

“const”断言只能应用于对枚举成员、字符串、数字、布尔值、数组或对象文字的引用。

我不确定我在这里缺少什么,因为Object.values确实返回了一个数组。为什么我不能对其进行 const 断言

Min*_*uel 2

X你不能这样做的原因是因为const 断言的左侧X as const必须是 TypeScript 编译器知道的文字值。

所以我假设你的最终目标是你想要拥有完整的 A 类型。没有任何特殊的东西你会得到这个:

const a: {
    label: Keys;
    id: string;
}[]
Run Code Online (Sandbox Code Playgroud)

现在如果你想得到这个:

const a: [
    {
        label: "one";
        id: "0";
    },
    {
        label: "two";
        id: "1";
    }
]
Run Code Online (Sandbox Code Playgroud)

这实际上是不可能的,因为你依赖于Object.values迭代顺序。这是由 ES2015 定义的,但打字稿类型不“知道”它。

通过一些简单的花哨类型,您可以获得:

type EnumEntry<T> = T extends any ? { label: T, id: string } : never;

const a: EnumEntry<Keys>[] = Object.values(Keys).map((value, index) => ({
  label: value,
  id: String(index)
}));
Run Code Online (Sandbox Code Playgroud)
const a: ({
    label: Keys.One;
    id: string;
} | {
    label: Keys.Two;
    id: string;
})[]
Run Code Online (Sandbox Code Playgroud)

但这是我认为我们可以做的最好的事情,而不取决于打字稿如何排序类型。