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

如何从TypeScript泛型实例中提取目标类名以省略多余方法入参

可以去掉第一个参数

你完全可以直接从实例上提取类名,不需要额外传构造函数作为第一个参数,简化后的写法如下:

function save<T extends object>(entity: T) {
    // 不需要调用Object.getPrototypeOf,直接取实例的constructor属性即可
    const apiPath = `/api/${entity.constructor.name.toLocaleLowerCase()}`
    return fetch(apiPath, {
        body: JSON.stringify(entity)
    })
}

// 调用方式可以简化为
backendService.save(new User('Fractaliste'))

本地运行与Playground结果不一致的原因

出现差异通常是以下两个原因导致的:

  • 编译目标版本不同
    你本地的tsconfig.json中的target配置大概率是ES5或更低版本,TypeScript在低版本ES目标下转译类语法时,会改写构造函数的实现,导致constructor.name属性不符合预期。而TypeScript官方Playground默认使用高版本ES目标(ESNext),类语法会被保留原生实现,所以运行结果符合预期。你可以把本地的target调整为ES6及以上版本验证这个问题。
  • 代码压缩混淆
    如果你的项目启用了打包压缩(比如Webpack的Terser插件、Vite默认的生产构建配置),压缩工具会默认把类名替换为无意义的短字符来减小包体积,这时候constructor.name会变成类似t、n的随机短名,自然和预期的类名不一致。

更稳定的实现方案

依赖运行时类名拼接接口路径的方式,始终会受编译、压缩配置的影响,更稳妥的方案是给每个实体类添加静态的端点标识,避免运行时获取类名:

// 实体类定义
class User {
    static apiEndpoint = 'user'
    constructor(public name: string) {}
}

// save方法实现
function save<T extends object>(entity: T) {
    const clazz = entity.constructor as typeof Object & { apiEndpoint: string }
    return fetch(`/api/${clazz.apiEndpoint}`, {
        body: JSON.stringify(entity)
    })
}

这种实现完全不受编译配置和代码压缩的影响,稳定性更高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:27:03