2017-04-11 58 views
0

我使用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 
     } 
    } 
} 
+0

https://github.com/ngrx/example-app/issues/127 – cartant

回答

2

的一種方式是投射屬性,以便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" }])); 

Code @ TypeScript Playground

輸出:

user: foo 
users: bar 
users: baz 

documentation非常好,有很多細節教你關於這個功能,並且所有的休息。

另一個好的來源是basarat.gitbooks.io