Я был бы склонен полностью забыть о enum
и вместо этого создавать свои собственные объекты, подобные перечислению. Это даст вам гибкость, необходимую для записи ключей только один раз, но вы потеряете часть встроенной выразительности, которая приходит с enum
(а именно, что enum Foo {...}
создает оба объекта с именем Foo
и типа с именем Foo
. Если вместо этого вы создадите const Foo = ...
, вы получите только объект , и вам нужно будет определить свой собственный тип самостоятельно, если вы этого хотите) .
Вот один из подходов:
const KeysAndPropNames = {
ID: { key: "ID", propName: "id" },
name: { key: "name", propName: "nm" }
} as const;
У вас есть только один объект, который является отображением ключа и значений, которые были в ваших старых перечислениях User.Keys
и PropertiesNamesInDataBase
. Вы можете самостоятельно извлечь эти перечислимые объекты следующим образом:
const User = { Keys: objMapProp(KeysAndPropNames, "key") };
const PropertiesNamesInDataBase = objMapProp(KeysAndPropNames, "propName");
, где objMapProp()
- это функция, которую вы можете поместить в библиотеку, которая отображает доступ к свойству для объекта:
// library
function objMapProp<T extends Record<keyof T, Record<K, any>>, K extends keyof any>(
obj: T,
key: K
) {
const ret = {} as { [P in keyof T]: T[P][K] };
for (let k in obj) {
ret[k] = obj[k][key];
}
return ret;
}
Если вы исследуете тип новых объектов User
и PropertiesNamesInDataBase
с помощью IntelliSense, вы увидите, что они соответствуют старым значениям:
/* const User: {
Keys: {
readonly ID: "ID";
readonly name: "name";
};
} */
/* const PropertiesNamesInDataBase: {
readonly ID: "id";
readonly name: "nm";
} */
Если вам нужны типы с именами User.Keys
и PropertiesNamesInDataBase
, вы можете сделать их как объединение всех типов значений соответствующих объектов:
namespace User {
export type Keys = (typeof User.Keys)[keyof typeof User.Keys];
// type User.Keys = "ID" | "name"
}
type PropertiesNamesInDataBase = typeof PropertiesNamesInDataBase[keyof typeof PropertiesNamesInDataBase];
// type PropertiesNamesInDataBase = "id" | "nm"
В любом случае, надеюсь, что это либо отвечает вашим потребностям, либо дает вам представление о том, как действовать дальше. Удачи!
Детская площадка ссылка на код