typescript - 如何区分 TypeScript 中结构相同的类型?
问题描述
我正在使用一个库,它有几个结构上等效的接口。像这样:
interface DataType { ... some stuff here ... }
interface DataTypeBoolean extends DataType {}
interface DataTypeJSON extends DataType {}
... around 20 more, not all of them equivalent
它给了我一个类型为:
def: {
flag: {
type: DataTypeBoolean;
};
data: {
type: DataTypeJSON;
};
}
我想生成一个将这些转换为原始类型的类型:
export type Types<T> = { [K in keyof T]:
T[K] extends { type: DataTypeBoolean } ? boolean :
T[K] extends { type: DataTypeJSON } ? object :
... some more clauses
undefined;
}
但是因为DataTypeBoolean
andDataTypeJson
是等价的,所以DataTypeJSON
产生and 因此,给了我:true
extends DataTypeBoolean
Types<def>
def: {
flag: boolean;
data: boolean;
}
为此Types<def>
,我必须找到某种方法来创建DataTypeBooleanStrict
和(DataTypeJsonStrict
这样我仍然可以尊重库接口),但也不能扩展,反之亦然。DataTypeBooleanStrict extends DataTypeBoolean
DataTypeJSONStrict extends DataTypeJSON
DataTypeBooleanStrict
DataTypeJSONStrict
我怎样才能做到这一点?
使用泛型类型来实现这一点会非常好,Strict<DataTypeBoolean>
而不是必须手动定义所有 30 个,但手动也比没有好。
解决方案
如前所述,TypeScript 中的类型系统是结构化的,因此具有相同形状的两个类型实际上是相同的类型,即使它们可能有不同的名称。处理这个问题的方法通常是修改你的类型,使它们在结构上和名义上都不同,如 TypeScript FAQ 条目中所述:“如何防止两种类型在结构上兼容?”
现在在这种情况下,有问题的界面显然位于您不能或不想触摸的库中。幸运的是,您可以使用声明合并来重新打开接口定义并向它们添加新属性。可能您想添加一些可选的东西,以便在运行时不存在实际的此类属性是可以的。例如:
///// DECLARATION MERGING //////
interface DataTypeBoolean {
__type?: "boolean"
}
interface DataTypeJSON {
__type?: "JSON"
}
///////////////////////////////
请记住,如果您从模块中导入接口,您可能需要使用declare module
合并定义,如手册中所示
declare module "./myLib" {
interface DataTypeBoolean {
__type?: "boolean"
}
interface DataTypeJSON {
__type?: "JSON"
}
}
无论如何,一旦我们这样做了,事情应该开始为你工作,因为编译器可以看到这些类型是不同的:
type Hmm = Types<Def>;
/* type Hmm = {
flag: boolean;
data: object;
} */
好的,希望有帮助。祝你好运!
推荐阅读
- wordpress - 如何在 woocommerce 的管理面板中禁用保存订单?
- reactjs - React-map-gl 动态 geoJson 文件导致错误 414 - URI 太长
- javascript - Microsoft Edge 中的语音识别 API(未定义)
- css - R Shiny中按索引号样式元素
- performance - 其中并发读/写操作的数据库策略
- debugging - 反汇编代码是崩溃同化的准确选择吗?
- ios - 我需要在 init(coder) 和 init(size) 中注入属性吗?
- php - 如何将 2 个按钮链接到同一页面上的 2 个单独的 php 代码?
- sharepoint-online - 如何使用 sp.web (SPFX) 获取文档库中文件的 URL
- c++ - 输出不是我所期望的