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

TypeScript寻找C# nameof替代方案,实现变量值等于自身变量名

需求说明

需要在TypeScript中创建值与自身变量名相等的只读字符串,实现C#中nameof函数的效果:C#中可以直接用public static readonly string Admin = nameof(Admin);得到值为"Admin"的变量,但TypeScript中原生不支持在变量初始化时调用自身,直接照搬写法会触发初始化前调用的错误。

C#可运行参考代码:

public static readonly string Admin = nameof(Admin);
// Admin最终取值为字符串"Admin"
原错误实现说明

最初尝试的TS代码如下:

export class Resources {
    static nameof(variable: Object): string{
        const keys = Object.keys(variable);
        return keys[0];
    }

    static readonly Admin = Resources.nameof(Resources.Admin);
}

运行时抛出错误:Property 'Admin' is used before its initialization.,错误原因是静态属性赋值阶段Resources.Admin还未完成初始化,无法作为参数传入函数。

可行解决方案

方案1:批量生成常量(推荐,适合多属性场景)

如果需要生成大量这类常量,可以通过泛型工具函数批量创建,同时保证类型安全:

// 定义类型约束,保证属性名和属性值严格一致
type ValueMatchKey<T extends string> = { readonly [K in T]: K };

function createConstants<T extends string>(keys: readonly T[]): ValueMatchKey<T> {
  return keys.reduce((result, key) => {
    result[key] = key;
    return result;
  }, {} as ValueMatchKey<T>);
}

// 用法:把所有需要的属性名传入数组即可
export const Resources = createConstants(['Admin', 'User', 'Editor', 'Guest'] as const);

实现效果:

  • Resources.Admin的值固定为"Admin",所有属性默认只读,无法修改
  • TypeScript可以自动推导每个属性的字面量类型,输入不存在的属性名会直接报类型错误
  • 新增属性只需要在传入的数组中加项即可,维护成本低

方案2:Getter实现(适合少量属性场景)

如果仅需要少量属性,可以直接用类的静态Getter模拟只读属性:

export class Resources {
  static get Admin(): 'Admin' { return 'Admin'; }
  static get User(): 'User' { return 'User'; }
  static get Guest(): 'Guest' { return 'Guest'; }
}

该写法没有初始化顺序问题,访问属性时返回对应名称的字符串,同样满足只读要求。

方案3:编译期替换(最接近C# nameof体验)

如果希望完全复用C#的nameof写法,可以通过自定义TypeScript编译插件,在编译阶段直接把nameof(变量)的调用替换为对应的字符串字面量,不需要运行时代码,也不会触发初始化顺序错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:39:02