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

TypeScript如何避免对象属性字符串字面量被拓宽为string类型

解决方案

1. 保留字面量类型避免拓宽

默认情况下TypeScript推导普通const对象的属性时,会将字符串/数字值拓宽为对应的基础类型(比如"string"字面量拓宽为string类型),要保留精确的字面量类型,直接给整个对象加as const断言即可:

const STUDY_TAGS = {
  InstanceAvailability: { tag: "00080056", type: "optional", vr: "string" },
  ModalitiesinStudy: { tag: "00080061", type: "required", vr: "string" },
  ReferringPhysiciansName: { tag: "00080090", type: "required", vr: "string" },
  NumberofStudyRelatedSeries: {
    tag: "00201206",
    type: "required",
    vr: "number",
  }
} as const;

此时typeof STUDY_TAGS会保留每个属性的精确字面量类型,比如InstanceAvailability.vr的类型是"string",NumberofStudyRelatedSeries.vr的类型是"number",不会被统一拓宽。

2. 同时增加类型校验不丢失精度

如果你需要约束对象的结构(比如限制vr只能是"string"/"number",type只能是"required"/"optional"),不要直接用Record做类型注解,这会抹掉每个字段的独立类型信息,改用TS 4.9以上支持的satisfies操作符,同时满足类型校验和保留字面量的需求:

// 先定义结构约束
type StudyTagMeta = {
  tag: string;
  type: "optional" | "required";
  vr: "string" | "number";
}

const STUDY_TAGS = {
  InstanceAvailability: { tag: "00080056", type: "optional", vr: "string" },
  ModalitiesinStudy: { tag: "00080061", type: "required", vr: "string" },
  ReferringPhysiciansName: { tag: "00080090", type: "required", vr: "string" },
  NumberofStudyRelatedSeries: {
    tag: "00201206",
    type: "required",
    vr: "number",
  }
} as const satisfies Record<string, StudyTagMeta>;

如果对象属性不符合StudyTagMeta的约束,TS会直接抛出错误,同时不会丢失每个字段的字面量类型。

3. 函数调用效果

你定义的doSomething函数本身逻辑是正确的,配合上面处理后的STUDY_TAGS,就能自动根据入参的vr值推导返回类型:

// 返回值类型自动推导为string
const res1 = doSomething(STUDY_TAGS.InstanceAvailability);
// 返回值类型自动推导为number
const res2 = doSomething(STUDY_TAGS.NumberofStudyRelatedSeries);

低版本TS兼容方案

如果你的TS版本低于4.9不支持satisfies,可以用泛型工具函数实现同样的效果:

type StudyTagMeta = {
  tag: string;
  type: "optional" | "required";
  vr: "string" | "number";
}

function defineStudyTags<T extends Record<string, StudyTagMeta>>(tags: T) {
  return tags;
}

const STUDY_TAGS = defineStudyTags({
  InstanceAvailability: { tag: "00080056", type: "optional", vr: "string" },
  ModalitiesinStudy: { tag: "00080061", type: "required", vr: "string" },
  ReferringPhysiciansName: { tag: "00080090", type: "required", vr: "string" },
  NumberofStudyRelatedSeries: {
    tag: "00201206",
    type: "required",
    vr: "number",
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:09:00