如何根据 TypeScript 中 const 对象的 keys/values 创建对象类型?

How to create an object type based on keys/values of a const object in TypeScript?

我需要定义一个基于配置对象的类型 (anObject),它将在我的代码中使用。

我写了类似下面的东西,

const anObject = {
  foo: ["a", "b", "c"],
  bar: ["d", "e", "f"],
} as const;

type aType =
  | { key: ""; value: [] }
  | { key: "foo"; value: ("a" | "b" | "c")[] }
  | { key: "bar"; value: ("d" | "e" | "f")[] };

const a: aType = { key: "", value: [] }; // No error
const b: aType = { key: "foo"; value: ["a", "b"] }; // No error
const c: aType = { key: "bar"; value: ["e", "f"] }; // No error

如何在 TypeScript 中动态声明 aType

这段代码怎么样?

const anObject = {
    foo: ["a", "b", "c"],
    bar: ["d", "e", "f"],
} as const;

type aType = {
    key: keyof typeof anObject | "";
    value: typeof anObject[keyof typeof anObject][number][];
} & (
    | { key: ""; value: undefined[] }
    | { key: "foo"; value: typeof anObject["foo"][number][] }
    | { key: "bar"; value: typeof anObject["bar"][number][] }
    );

const foo: aType = { key: "", value: [] };

我只是添加了未定义的类型,这样就不会出现 TypeScript 错误。解决了您的问题?

第二个问题是一个简单的实现错误,因为如果您的类型基于配置对象,请确保您的类型必须具有它的所有属性。所以你必须改变你的方法。如果您能更详细的说明您的需求,我或许能帮到您。

我知道现在这很牵强,但你会不会想要这样:

export interface MyConfiguration {
    foo?: ("a" | "b" | "c")[],
    bar?: ("d" | "e" | "f")[],
}

const DefaultMyConfiguration: MyConfiguration = {
    foo: ["b", "c"],
    bar: ["d"]
}

//In the middle of somewhere in your code you can now do this
let config: MyConfiguration
function myConstructor(config: MyConfiguration) {
    config = {...DefaultMyConfiguration, ...config}
}

这里值得使用联合:

const anObject = {
    foo: ["a", "b", "c"],
    bar: ["d", "e", "f"],
} as const;

type AnObject = typeof anObject;

type Values<T> = T[keyof T]

type AType = {
    [P in keyof AnObject]: {
        key: P,
        value: Array<AnObject[P][number]>
    }
}

type Default = { key: ""; value: [] }

type Result = Values<AType> | Default

const foo: Result = { key: "", value: [] }; // ok
const bar: Result = { key: "bar", value: ["d"] } // ok

随时向 anObject 添加任何新密钥。您无需在其他任何地方进行更新

请记住,正如@T.J克劳德所说,value属性中没有顺序。 TS 将允许不同的值组合:[d,e] | [e, d] | [d].

如果你想要以相同的顺序使用它,只需使用这一行:value: AnObject[P] in AType helper