Typescript防止将字符串字面值泛化为类型



所以我有这个常量Object

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

我可以强制typescript保留字符串字面值,而不是将它们泛化为字符串类型吗?我想定义的对象类型为Record<string,>

Record<string, {
tag: string;
type: string;
vr: "string" | "number";
}
我真的很困惑,不知道如何解决这个问题。难道不应该以某种方式根据具有两个字符串值之一的对象推断返回类型吗?最后,我想创建一个函数,它接受对象并根据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的特定用例。

您应该能够将类型声明为const

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',这样你就可以看到区别了。您可以将这些属性添加到上面的任何属性中,以获得确切的值,而不是原始值。

我的主要问题是没有从对象中获得类型信息,因为它会将我的字符串常量泛化为一般类型字符串,尽管我用Object.freeze()定义了我的对象。解决方案是这样定义对象:

const obj = {a: {test: "hi"}} as const;

最新更新