typescript-将类型分配给多个类型的导出变量

typescript-将类型分配给多个类型的导出变量,typescript,ngrx,Typescript,Ngrx,我使用的是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 = Act

我使用的是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
我现在的减速机出了问题。由于导出的操作可以是User或User[]类型,因此不允许我将userlist:User[]分配给它(我希望使用forEach之类的数组方法)

export function reducer(状态=初始状态,操作:userAction.Actions):状态{
开关(动作类型){
案例userAction.ActionTypes.SET_用户列表:{

let userlist:User[]=action.payload处理此问题的一种方法是强制转换属性,以便TypeScript知道它应该是什么类型

let userlist:User[] = <User[]>action.payload;
但这并没有真正发挥类型系统的全部潜力,而且代码也不是很好

与其使用强制转换将类型强制为特定类型,不如告诉类型系统如何确定它是什么类型

所以…听起来你需要类型守卫


(查找标题为“用户定义类型保护”的部分)

您可以创建一个特殊函数,用于测试对象是否属于特定类型。
该函数返回布尔值,匹配为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" }]));
这是非常好的,有很多细节教你关于这个功能,以及所有其他的


另一个好的来源是。

处理这个问题的一种方法是强制转换属性,以便TypeScript知道它应该是什么类型

let userlist:User[] = <User[]>action.payload;
但这并没有真正发挥类型系统的全部潜力,而且代码也不是很好

与其使用强制转换将类型强制为特定类型,不如告诉类型系统如何确定它是什么类型

所以…听起来你需要类型守卫


(查找标题为“用户定义类型保护”的部分)

您可以创建一个特殊函数,用于测试对象是否属于特定类型。
该函数返回布尔值,匹配为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" }]));
这是非常好的,有很多细节教你关于这个功能,以及所有其他的

另一个好消息来源是