繁体   English   中英

打字稿防止将字符串文字泛化为类型

[英]Typescript prevent generalization of string literal to type

所以我有这个常量对象

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",
  }
};

现在我想根据每个对象的 vr 值推断其返回类型,但是如果我查看 typeof STUDY_TAGS,所有键值对看起来都一样:

 InstanceAvailability: {
        tag: string;
        type: string;
        vr: string;
    };

我可以以某种方式强制打字稿保留字符串文字而不是将它们概括为类型字符串吗? 我想用 Record<string, {tag: string, type: string, vr: "string" | 类型定义对象 "number"}> 但是我在查看 typeof STUDY_TAGS 时得到的只是

Record<string, {
    tag: string;
    type: string;
    vr: "string" | "number";
}

我真的迷失在这里,不知道如何解决这个问题。 是否应该可以根据具有 2 个字符串值之一的对象推断返回类型? 最后我想创建一个函数,它接受对象并根据 vr 值知道返回的类型

function doSomething<Type extends "number" | "string">({tag, type, vr} : {tag : string, type : string, vr: Type}) : Type extends "number" ? number : string
{
 if(vr === "string") return "test";
 return 0;
}

我相信函数重载和缩小可以帮助你。 这是一个简化的示例:

function doSomething(vr: 'string'): string
function doSomething(vr: 'number'): number
function doSomething(vr: string): string | number {
  if(vr === 'string) return 'Test!';
  return 0;
}

然后,当您调用doSomething ,TypeScript 的类型系统可以推断返回类型,因为您告诉它每当vr等于'string' ,该函数返回一个字符串,并且每当vr等于'number' ,该函数返回一个数字.

const foo = doSomething('string'); // TypeScript knows 'foo' is a string
const bar = doSomething(2); // TypeScript know 'bar' is a number

这是一个更完整的示例,其中包含您在 TypeScript 操场上的特定用例。

感谢您尝试提供帮助。 我的主要问题不是从对象中获取类型信息,因为它会将我的字符串常量概括为一般类型字符串,尽管 iÍ 使用 Object.freeze() 定义了我的对象。 解决方案是像这样定义对象: const obj = {a: {test: "hi"}} as const;

我在 Typescript 文档中没有找到这个,所以我在这个问题上花了一些不必要的时间。 有了这个解决方案,剩下的就很容易了。

您应该能够将类型声明为“作为常量”

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

上面我刚刚为type属性添加了“as const”,以便您可以看到不同之处。 您可以将这些添加到上面的任何属性中以获得确切的值而不是它们的原始值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM