我正在使用nrgx / store并按照示例应用程序使用类来强力键入我的操作,例如
export const ActionTypes ={
SET_ACTIVE_USER: type('[UserState] Set Active User'),
SET_USERLIST: type('[UserState] Set Userlist')
};
export class SetActiveUserAction implements Action {
type = ActionTypes.SET_ACTIVE_USER;
constructor(public payload:User){}
}
export class SetUserlistAction implements Action {
type = ActionTypes.SET_USERLIST;
constructor(public payload:User[]){}
}
export type Actions
= SetActiveUserAction
| SetUserlistAction
我现在在我的减速机中遇到了类型问题。由于导出的Actions可以是User或User []类型,它不允许我为其分配用户列表:User [](我想使用像forEach这样的数组方法)
export function reducer(state = INITIAL_STATE, action: userAction.Actions): State {
switch (action.type) {
case userAction.ActionTypes.SET_USERLIST: {
let userlist:User[] = action.payload <-------Type Issue
return tassign(state, { userlist: action.payload })
}
default: {
return state
}
}
}
答案 0 :(得分:2)
处理此问题的一种方法是强制转换属性,以便TypeScript知道它应该是什么类型。
let userlist:User[] = <User[]>action.payload;
如果这不起作用,那么您可以转换为any
,然后转换为该类型。
let userlist:User[] = <User[]><any>action.payload;
但那并没有真正使用类型系统来充分发挥它的潜力,而且代码也不是很好。
如果我们可以告诉类型系统如何确定它是什么类型,那么它不是强制使用类型转换为特定类型,而是很好。
所以......听起来你想要Type Guards。
https://www.typescriptlang.org/docs/handbook/advanced-types.html
(查找标题为&#39;用户定义类型保护&#39;)的部分
您可以创建一个特殊函数来测试某个对象是否属于某种类型 该函数返回一个bool,匹配为true,不匹配为false 在代码中使用该函数测试变量时,TypeScript会识别类型测试并更改该变量的类型以匹配测试类型。
所以你最终会得到这样的代码:
if (isUserAction(action)) {
let user: IUser = action.Payload;
}
我无法让他们使用您所拥有的确切对象布局,但我做了一个类似的例子,其中包含一些允许类型保护工作的调整。
enum ActionType { User = 1, Users = 2 }
interface IAction { Type: ActionType; }
interface IUser { Name: string; }
class Action<T> implements IAction {
public Type: ActionType;
public Payload: T;
constructor(type: ActionType, payload: T) {
this.Type = type;
this.Payload = payload;
}
}
class UserAction extends Action<IUser> {
constructor(payload?: IUser) {
super(ActionType.User, payload);
}
}
class UsersAction extends Action<IUser[]> {
constructor(payload?: IUser[]) {
super(ActionType.Users, payload);
}
}
function isUserAction(action: IAction): action is UserAction {
return action.Type === ActionType.User;
}
function isUsersAction(action: IAction): action is UsersAction {
return action.Type === ActionType.Users;
}
function processAction(action: IAction) {
if (isUserAction(action)) {
let user: IUser = action.Payload;
console.log(`user: ${user.Name}`);
} else if (isUsersAction(action)) {
let users: IUser[] = action.Payload;
for (let user of users) {
console.log(`users: ${user.Name}`);
}
}
}
processAction(new UserAction({ Name: "foo" }));
processAction(new UsersAction([{ Name: "bar" }, { Name: "baz" }]));
输出:
user: foo
users: bar
users: baz
documentation非常好,并且有很多详细信息可以教你这些功能以及所有其他功能。
另一个好消息来源是basarat.gitbooks.io。