打字稿 - 指定类型的多种类型
问题描述:
我使用nrgx /存储和下面的示例应用程序,我使用类强类型我的动作像打字稿 - 指定类型的多种类型
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
我现在正在为一个导出变量在我的减速机中输入问题。由于导出操作的类型可以是用户或用户的[],它不会让我分配用户列表:用户[]它(我想使用数组方法,如的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
}
}
}
答
的一种方式是投射属性,以便TypeScript知道它应该是什么类型。
let userlist:User[] = <User[]>action.payload;
如果不工作,那么你可以转换为any
再到类型。
let userlist:User[] = <User[]><any>action.payload;
但是,这不是真的使用类型系统来充分发挥其潜力,而且不是很好的代码。
如果我们可以告诉类型系统如何确定它是什么类型,那么不是强制类型成为使用类型转换的特定类型。
所以...这听起来像你想要的类型近卫。
https://www.typescriptlang.org/docs/handbook/advanced-types.html
(查找标题为“用户定义类型卫队)
您可以用来测试对象是否是某种类型的特殊功能。
该函数返回一个布尔值,对于匹配返回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。
https://github.com/ngrx/example-app/issues/127 – cartant