typescript - 将类型映射到字符串属性
问题描述
我有一堆数据类型,它们都包含一个属性dataType
,我将每个类型映射到该值:
interface GroupData {
dataType: "group";
name: string;
people: PersonData[];
}
interface PersonData {
dataType: "person";
name: string;
email: string;
messages: MessageData[];
}
interface MessageData {
dataType: "message";
message: string;
timestamp: number;
}
interface DataTypeMap {
group: GroupData;
person: PersonData;
message: MessageData;
}
这符合我的目的,但有点手动。在我的实际应用程序中,我有更多的数据类型,并且它们经常变化。我想要的是能够使这个过程自动化一点。到目前为止,这与我来的一样接近:
type DataType = GroupData
| PersonData
| MessageData;
type DataTypeMap = {
[(T in DataType)["dataType"]]: T;
};
调节单个数据类型的联合比键必须具有特定值的映射要容易得多;但是,这在 TypeScript 中并不符合犹太教规。我收到以下 TS 错误:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
Cannot find name 'T'.
'DataType' only refers to a type, but is being used as a value here.
据我所知,这些都是我的语法问题。我 90% 确定您不能使用in
非字符串的联合,并且在索引签名中使用括号选择器感觉像是一种延伸。
是否可以根据所有数据类型都具有的属性映射数据类型列表?
解决方案
你是如此接近!这就是我们想要的:
type DataTypeMap = {
[T in DataType['dataType']]: Extract<DataType, {dataType: T}>;
};
DataType
是所有类型接口的并集。 DataType['dataType']
是所有类型名称字符串文字的并集。
在我们的地图中,我们说键是那些string
名称。对于每个键,我们都想找到对应的interface
. 我们使用Extract
只获取可以拥有的工会成员{dataType: T}
。
这解决了:
type DataTypeMap = {
group: GroupData;
person: PersonData;
message: MessageData;
}
推荐阅读
- javascript - 使用 HTML 标签处理服务器响应
- android - java.lang.NoClassDefFoundError: com.google.android.gms.auth.api.signin.GoogleSignInAccount
- django - Django:使用通道的实时数据库
- python-3.x - AttributeError:“Figure”对象在 Flask 中没有属性 savefig
- java - 如何解决 S3 错误:org.jets3t.service.S3ServiceException:S3 GET 失败?爪哇
- mysql - 在连接到远程 mysql(从本地)时出现此错误
- swift - 如何在 StackView 中展开 UITableView?
- python - Python librosa NoBackendError 即使安装了 ffmpeg
- c++ - 尝试访问地图中不存在的密钥时程序崩溃
- go - 在响应正文之前获取状态