使用对象字面量的键作为 Typescript 类型,即使对象字面量也是类型化的?

问题描述 投票:0回答:1

我想在其他地方使用对象的键作为类型,并在这里找到了解决方案:使用对象文字的键作为 Typescript 类型?

但是,就我而言,我还希望对原始对象文字进行类型限制,以便在处理它时我有 Typescript 支持。 但这样做会导致类型推断不再像链接的解决方案中那样工作。

举个例子: 我希望能够使用如下所示的数据键:

const data = Object.freeze({
    some: "abc",
    long: {"a":"b"},
    list: ["c"],
    of: "",
    things: "b",
});

type data_key = keyof typeof data;

// leads to:
// type data_key = "some" | "long" | "list" | "of" | "arbitrary" | "things"

但是当我向

data
添加类型时,这就不再可能了:

const data: { [key: string]: string | object } = Object.freeze({
    some: "abc",
    long: {"a":"b"},
    list: ["c"],
    of: "",
    things: "b",
});

type data_key = keyof typeof data;

// leads to:
// type data_key = string | number

第一个示例中的类型推断似乎以某种方式被覆盖。有没有什么方法可以结合这两个示例,以便为对象文字提供类型,然后从该对象文字的键推断出新类型?

typescript type-inference
1个回答
0
投票

发生这种情况的原因是因为在第二个示例中,您显式地将

data
对象的键类型设置为
string
类型而不是
"some" | "long" | "list" | "of" | "arbitrary" | "things"
类型。这是正确的 Typescript 行为。

尽管我不确定为什么这会有用,但一种可能的方法是:

enum PossiblKeys {
  some = 'some',
  long = 'long',
  list = 'list',
  of = 'of',
  things = 'things',
}

const data: Record<PossiblKeys, string | object> = {
  some: "abc",
  long: {"a":"b"},
  list: ["c"],
  of: "",
  things: "b",
};

type data_key = `${keyof typeof data}`;

首先,您必须使用将用于

data
对象的键定义一个枚举,然后您可以使用最后一行中的语法从对象中检索所有键并将它们转换为联合类型。请注意,这与执行
${PossibleKeys}
相同,但我假设您有特定需要从
data_key
专门构建
data

© www.soinside.com 2019 - 2024. All rights reserved.