typescript - 打字稿:从枚举值生成具有映射属性的对象
问题描述
我正在寻找一种方法来生成一个对象,该对象在编译期间从枚举值和预定义的函数调用中计算出的值 - 基本上这个想法是将函数的一些参数与键绑定。例如,假设我有以下内容:
enum LogLevel {
error = 'error',
warning = 'warning'
info = 'info'
}
const log = (level: LogLevel, message: string) => {
console.log(`Level: ${level}, Message: ${message}`);
}
我正在寻找如下语法:
const logger = {
[level in LogLevel]: (msg: string) => log(level, msg)
}
这不起作用(编译失败A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
)
我希望它在功能上等于:
const logger = {
[LogLevel.error]: (msg: string) => log(LogLevel.error, msg),
[LogLevel.warning]: (msg: string) => log(LogLevel.warning, msg),
[LogLevel.info]: (msg: string) => log(LogLevel.info, msg)
}
这样我就可以这样使用它:
logger.error("Bad things happened")
logger.warn("Help me")
实际用例在枚举中包含许多元素,我宁愿在每次添加新元素时都不要修改对象。我知道我至少可以添加一个类型约束,该约束要求枚举中的所有键都以非常相似的语法出现在类型中:
type Logger = {
[level in LogLevel]: (msg: string) => void
}
但由于这些值是重复的并且实际上只是样板文件,我希望它们能够自动生成。
解决方案
这里唯一要记住的是,TypeScript
类型在编译为 JavaScript 后会被剥离,因此您需要Logger
动态生成。
const allLogLevels = ['error', 'warning', 'info'] as const;
type LogLevel = typeof allLogLevels[number]; // 'error' | 'warning' | 'info'
type Logger = {
[level in LogLevel]: (msg: string) => void
}
const log = (level: LogLevel, message: string) => {
console.log(`Level: ${level}, Message: ${message}`);
}
function createLogger() {
const logger: Partial<Logger> = {};
for (let key of allLogLevels) {
logger[key] = (message: string) => log(key, message);
}
return logger as Logger;
}
// runtime
const logger = createLogger();
logger.error('test error.');
logger.warning('test warning.');
logger.info('test info.');
TypeScript Playground 示例在这里。
推荐阅读
- firebase - 如何从 Firbase 数据库中获取特定数据
- mysql - mysql,当我向选择中添加一列时,结果会有所不同
- sql - Grafana 更改 SQL 查询以汇总每个数据点
- liquid - 乘以字符串格式的合并标签
- apache-spark - pyspark - 如何加快重采样和联合所有
- java - Spring Boot 中的 Classpath VS Target 文件夹
- node.js - 限制从 node.js 中的身份验证页面重定向到主页
- pnpm - 我们可以从其他克隆的存储库中添加一个包并在本地构建为另一个 rush monorepo 中的本地依赖项吗
- java - Spring Integration JMS/IBM MQ:如果没有收到响应,我该如何对其进行业务逻辑
- pytorch - 在 PyTorch 的 nn.Sequential 层中使用 torch.square()