You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TypeScript泛型参数的日志函数编译优化:移除无效调用

问题:编译时移除无效日志函数调用

现有一段JavaScript代码,通过键值对控制日志是否输出:

const LoggedKeys = {
  logged: true,
  ignored: false,
}
function log(key, msg) {
  if(LoggedKeys[key]) console.log(msg);
}
log('logged', "This should be logged")
log('ignored', "That should not do anything")

需求是将其改写为TypeScript版本,让对应值为false的键的log函数调用在编译时被移除,或生成空函数调用,以此避免大量无效调用带来的性能损耗。期望的使用方式大致如下:

interface LoggedKeys {
  logged: true,
  ignored: false,
}
type MyLogFunction<T extends keyof LoggedKeys> = LoggedKeys[T] extends true? (msg) => void: never
// 使用示例
log<"logged">("That would generate proper log function")
log<"ignored">("That would be erased during compilation or generate fake empty function during compilation")

解决方案

可以通过TypeScript字面量类型收窄、条件类型,结合构建工具的Tree-shaking能力实现需求,具体步骤如下:

1. 精确约束日志配置类型

用as const断言锁定日志配置的字面量值,让TypeScript能精准识别启用/禁用的日志键:

const LogConfig = {
  logged: true,
  ignored: false,
} as const;

type LogKey = keyof typeof LogConfig;
// 筛选仅启用的日志键
type EnabledLogKey = {
  [K in LogKey]: typeof LogConfig[K] extends true ? K : never;
}[LogKey];

2. 编写带类型校验的日志函数

通过函数重载区分启用/禁用键的调用逻辑,启用键正常输出日志,禁用键执行空逻辑:

// 重载:启用键的有效调用
function log(key: EnabledLogKey, msg: string): void;
// 重载:禁用键的空调用
function log(key: Exclude<LogKey, EnabledLogKey>, msg: string): void;

function log(key: LogKey, msg: string) {
  LogConfig[key] && console.log(msg);
}

3. 用Tree-shaking彻底移除无效调用

上述代码编译后,禁用键的log调用会保留空执行逻辑。若要彻底清除这些调用,需配合构建工具的Tree-shaking:

  • 确保tsconfig.json中module设为ESNext/ES2020等ES模块格式;
  • 生产模式构建(如Webpack的mode: "production")时,Tree-shaking会自动移除无副作用的空调用。

泛型风格实现(匹配你的期望示例)

如果想用泛型指定键的方式调用,可采用以下写法:

type LogFn<T extends LogKey> = typeof LogConfig[T] extends true 
  ? (msg: string) => void 
  : () => void;

function log<T extends LogKey>(key: T): LogFn<T> {
  return LogConfig[key] 
    ? (msg: string) => console.log(msg) as LogFn<T>
    : (() => {}) as LogFn<T>;
}

// 使用示例
log("logged")("This will output to console");
log("ignored")("This call will be removed in production build");

这种方式下,禁用键对应的日志函数是空实现,生产构建时会被Tree-shaking完全移除,不会产生任何性能开销。

内容的提问来源于stack exchange,提问作者mmierzwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:10:30