如何在TypeScript中区分结构相同的类型?

如何在TypeScript中区分结构相同的类型?,typescript,Typescript,我正在使用一个库,它有几个在结构上等价的接口。像这样: 接口数据类型{…这里有些东西…} 接口DataTypeBoolean扩展数据类型{} 接口DataTypeJSON扩展数据类型{} ... 大约20多个,不是所有的都相等 它给了我一个对象,它的类型是: def:{ 旗帜:{ 类型:DataTypeBoolean; }; 数据:{ 类型:DataTypeJSON; }; } 我想生成一个类型,将这些类型转换为基本类型: export type={[K in keyof T]: T[K]扩

我正在使用一个库,它有几个在结构上等价的接口。像这样:

接口数据类型{…这里有些东西…}
接口DataTypeBoolean扩展数据类型{}
接口DataTypeJSON扩展数据类型{}
... 大约20多个,不是所有的都相等
它给了我一个对象,它的类型是:

def:{
旗帜:{
类型:DataTypeBoolean;
};
数据:{
类型:DataTypeJSON;
};
}
我想生成一个类型,将这些类型转换为基本类型:

export type={[K in keyof T]:
T[K]扩展了{type:DataTypeBoolean}?boolean:
T[K]扩展{type:DataTypeJSON}?对象:
……还有一些条款
未定义;
}
但是因为
DataTypeBoolean
DataTypeJson
是等价的,
DataTypeJson
产生
true
for
扩展了DataTypeBoolean
,因此,
Types
给了我:

def:{
标志:布尔;
数据:布尔型;
}
为了使
类型
起作用,我必须找到一些方法来创建
DataTypeBooleanStrict
DataTypeJsonStrict
,以便
DataTypeBooleanStrict扩展DataTypeBoolean
DataTypeJsonStrict扩展DataTypeJSON
(这样我仍然可以尊重库接口),但是,
DataTypeBooleanStrict
也不扩展
datatypejsonstrct
,反之亦然

我怎样才能做到这一点


如果使用像
Strict
这样的泛型类型,而不必手动定义所有30个类型,那将是非常好的,但是手动也比没有好。

正如已经指出的,TypeScript中的类型系统是,因此具有相同形状的两个类型实际上是相同的类型,尽管他们可能有不同的名字。处理此问题的方法通常是修改您的类型,使它们在结构上和名义上有所不同,如TypeScript常见问题解答条目中所述:

现在,在这种情况下,有问题的接口显然在一个你不能或不想触摸的库中。幸运的是,您可以使用重新打开接口定义并向其添加新属性。可能您想添加一些可选的内容,这样在运行时就不存在实际的此类属性了。例如:

///// DECLARATION MERGING //////
interface DataTypeBoolean {
    __type?: "boolean"
}
interface DataTypeJSON {
    __type?: "JSON"
}
///////////////////////////////
请记住,如果要从模块导入接口,可能需要在合并定义周围使用
declare module
,如


无论如何,一旦我们这样做,事情应该开始为您工作,因为编译器可以看到这些类型是不同的:

type Hmm = Types<Def>;
/* type Hmm = {
    flag: boolean;
    data: object;
} */
type-Hmm=类型;
/*类型Hmm={
标志:布尔;
资料:对象;
} */
好的,希望能有帮助。祝你好运


我认为你不能,因为TS类型系统是结构化的,也就是说,它不在乎你的东西是如何命名的。一个现实的选择是使用标记的联合,这样你的类型在结构上就不同了。这比我预期的要好得多!TIL关于合并来自外部依赖项的类型的声明。太棒了。按照你的建议,我可以简化我的类型。拥有
声明模块'theLib'{interface DataTypeBoolean{{uuuuu type?:boolean}
我可以使用:
导出类型={[K in keyof T]:T[K]扩展{type:{uuuuuu type?:推断U}?U:undefined;
type Hmm = Types<Def>;
/* type Hmm = {
    flag: boolean;
    data: object;
} */