我有一个用于通过套接字连接来回传递 JSON 消息的系统。它使用标记联合来表示消息类型:
export type ErrorMessage = { kind: 'error', errorMessage: ErrorData };
export type UserJoined = { kind: 'user-joined', user: UserData };
// etc
export type Message = ErrorMessage | UserJoined | /*etc*/;
Run Code Online (Sandbox Code Playgroud)
它在基本代码中运行得相当好,但我在其之上构建了一个模块,我想扩展代码。我要添加一个新的消息类型:
export type UserAction = { kind: 'user-action', action: Action }
Run Code Online (Sandbox Code Playgroud)
这里的问题是我无法扩展“Message”以将我的新 UserAction 包含到联合中。我想我可以制作自己的扩展消息:
export type ExtendedMessage = Message | UserAction;
Run Code Online (Sandbox Code Playgroud)
但这里的问题是,第一,这看起来很笨拙。我无法将新的 UserAction 传递到任何需要消息的方法中,即使代码实际上应该完全正常工作。以后想要扩展我的模块和基本模块的任何人都需要创建第三种类型:export type ExtendedMessageAgain = ExtendedMessage | MyNewMessage。
所以。我已经看到通过添加新的 .d.ts 文件来扩展附加属性的接口(例如 Passport 如何扩展 Express JS 的 Request 对象以添加身份验证属性),我认为标记联合也必须存在类似的东西,对吗?
但事实似乎并非如此。我用谷歌搜索了一下,没有看到这种模式在任何地方使用。这让我相信我的设计也许在某种程度上是错误的。但我没有看到解决办法。
我不想使用类,因为类型信息会通过网络被删除;该kind财产必须存在。我喜欢这个范例: …
我有一个区别的联合类型,它根据字符串文字字段区分类型.我想派生一个映射类型,它将联合中的所有类型映射到它们对应的鉴别器文字值.
例如
export type Fetch = {
type: 'fetch',
dataType: string
};
export type Fetched<T> = {
type: 'fetched',
value: T
};
// union type discriminated on 'type' property
export type Action =
| Fetch
| Fetched<Product>;
// This produces a type 'fetch' | 'fetched'
// from the type
type Actions = Action['type'];
// I want to produce a map type of the discriminator values to the types
// comprising the union type but in an automated fashion similar to …Run Code Online (Sandbox Code Playgroud)