我们正在使用带有Angular / TypeScript的ngrx。为了向Actions添加一些类型安全性,我们创建了以下
export interface TypedAction<T> extends Action {
type: string;
payload: T;
}
export class ExtensionRegistrationAction implements TypedAction<ExtensionRegistrationPayload> {
readonly type = ExtensionActionTypes.REGISTER_EXTENSION;
constructor(public payload: ExtensionRegistrationPayload) {}
}
export class ExtensionRegistrationSucceededAction implements TypedAction<void> {
readonly type = ExtensionActionTypes.REGISTER_EXTENSION_SUCCESS;
constructor(public payload: void) {}
}
export class ExtensionRegistrationFailedAction implements TypedAction<{messageCode: string}> {
readonly type = ExtensionActionTypes.REGISTER_EXTENSION_FAILURE;
constructor(public payload: {messageCode: string}) {}
}
export type ExtensionActions = ExtensionRegistrationAction
| ExtensionRegistrationFailedAction
| ExtensionRegistrationSucceededAction;
// The above lets us do the following
export function appExtensionsReducer(state: AppExtensionState = initialAppExtensionsState,
action: ExtensionActions): AppExtensionState {
switch (action.type) {
case ExtensionActionTypes.REGISTER_EXTENSION:
const registerAction = action as ExtensionRegistrationAction;
return {
registrations: state.registrations.concat(registerAction.payload)
};
// Handle other actions...
default: {
return state;
}
}
}
为了摆脱锅炉位置代码,我想我可以创建一个生成这些类的函数。
export function createTypedActionConstructor<T>(type: string): TypedAction<T> {
return class TypedActionImpl implements TypedAction<T> {
readonly type = type;
constructor(public payload: T) {}
}
}
但是我得到一个错误,因为我返回的是实现TypedAction的类,而不是实例。错误说:
TS2322类型'typeof TypedActionImpl'不能分配给'TypedAction'类型。财产“类型”缺失。
我做了什么工作
以下代码通过要求两个声明来解决问题,一个用于实现T
的接口,另一个用于创建该类型T
的工厂函数。问题在于它对锅炉板代码膨胀没有多大帮助。
export function createTypedActionFactory<T>(type: string): (payload: T) => TypedAction<T> {
return function(payload: T): TypedAction<T> {
return {type, payload};
}
}
// Now to create an action I need the two statements
export interface ExtensionRegistrationAction extends TypedAction<ExtensionRegistrationPayload> {}
export const createExtensionRegistrationAction = createTypedActionFactory<ExtensionRegistrationPayload>(
ExtensionActionTypes.REGISTER_EXTENSION);
问题 是否无法从TypeScript返回泛型类的动态实现?
答案 0 :(得分:2)
应该是:
export function createTypedActionConstructor<T>(type: string): { new (payload: T): TypedAction<T> } {
...
}
另一种选择是添加多个功能签名:
export function createTypedActionConstructor(type: ExtensionActionTypes.REGISTER_EXTENSION_FAILURE): { new (payload: {messageCode: string}): ExtensionRegistrationFailedAction };
export function createTypedActionConstructor(type: ExtensionActionTypes.REGISTER_EXTENSION_SUCCESS): { new (payload: void): ExtensionRegistrationSucceededAction };
...