{"action":"closed","issue":{"url":"https://api.github.com/repos/ngrx/platform/issues/255","repository_url":"https://api.github.com/repos/ngrx/platform","labels_url":"https://api.github.com/repos/ngrx/platform/issues/255/labels{/name}","comments_url":"https://api.github.com/repos/ngrx/platform/issues/255/comments","events_url":"https://api.github.com/repos/ngrx/platform/issues/255/events","html_url":"https://github.com/ngrx/platform/issues/255","id":249162391,"number":255,"title":"Error with typed actions (discriminated unions) in 4.0.2","user":{"login":"philipglaser","id":3208817,"avatar_url":"https://avatars0.githubusercontent.com/u/3208817?v=4","gravatar_id":"","url":"https://api.github.com/users/philipglaser","html_url":"https://github.com/philipglaser","followers_url":"https://api.github.com/users/philipglaser/followers","following_url":"https://api.github.com/users/philipglaser/following{/other_user}","gists_url":"https://api.github.com/users/philipglaser/gists{/gist_id}","starred_url":"https://api.github.com/users/philipglaser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/philipglaser/subscriptions","organizations_url":"https://api.github.com/users/philipglaser/orgs","repos_url":"https://api.github.com/users/philipglaser/repos","events_url":"https://api.github.com/users/philipglaser/events{/privacy}","received_events_url":"https://api.github.com/users/philipglaser/received_events","type":"User","site_admin":false},"labels":[{"id":669604823,"url":"https://api.github.com/repos/ngrx/platform/labels/Needs%20Reproduction","name":"Needs Reproduction","color":"fbca04","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2017-08-09T21:08:15Z","updated_at":"2017-08-17T13:12:03Z","closed_at":"2017-08-17T13:12:02Z","body":"## I'm submitting a...\r\n<!-- Check one of the following options with \"x\" -->\r\n<pre><code>\r\n[ ] Regression (a behavior that used to work and stopped working in a new release)\r\n[x ] Bug report  <!-- Please search GitHub for a similar issue or PR before submitting -->\r\n[ ] Feature request\r\n[ ] Documentation issue or request\r\n[ ] Support request\r\n</code></pre>\r\n\r\nI believe my issue is the same as was reported in https://github.com/ngrx/example-app/issues/151. \r\n\r\nI am just getting started with using store. I am starting with a simple action and reducer, where each action has a payload of a different type (GobiiFileItem or GobiiFileItem[]). In the reducer, I am getting a compile error to the effect that the payload is the wrong type: \r\n\r\n````Error:(58, 19) TS2322:Type 'GobiiFileItem | GobiiFileItem[]' is not assignable to type 'GobiiFileItem'.\r\n  Type 'GobiiFileItem[]' is not assignable to type 'GobiiFileItem'.\r\n    Property '_fileItemUniqueId' is missing in type 'GobiiFileItem[]'.\r\n````\r\n\r\nI have adapted the code from the example app in the version 4 repo, and search through various reports of the same issue, but nothing I try fixes the issue. \r\n\r\nEnvironment: \r\n* IntelliJ 2017.2.1\r\n* Typescript 2.4.1\r\n* npm 5.2.0 (5.3.0 doesn't work on Windows 10)\r\n* nodejs 6.11.2\r\n\r\n\r\nOne difference between my setup and the one in the example app that I am curious about is that the example app's tsconfig has this: \r\n\r\n````    \"lib\": [\r\n      \"es2016\",\r\n      \"dom\"\r\n    ],\r\n````\r\nThings I've tried: \r\n* Added the es2016 lib to my tsconfig:  This caused a ton of duplicate identifier errors from many node_module packages; but if that might be the source of the problem I can trying figuring that out. \r\n* Cloned the entire platform project to my system: \r\n..* I am able to compile and run the example app with npm run example:start; \r\n..* Compiling the example app in IntelliJ seemed to work except that the IDE was still reporting a number of other unrelated typescript errors that were completely different from discriminated union issue;\r\n\r\nThe action: \r\n\r\n````import {Action} from '@ngrx/store';\r\nimport {GobiiFileItem} from \"../../model/gobii-file-item\";\r\n\r\nexport const LOAD = '[GobiiFileItem] Load';\r\nexport const SELECT_FOR_EXTRACT = '[GobiiFileItem] Select';\r\nexport const DESELECT_FOR_EXTRACT = '[GobiiFileItem] DeSelect';\r\n\r\nexport class LoadAction implements Action {\r\n    readonly type = LOAD;\r\n\r\n    constructor(public payload: GobiiFileItem[]) {\r\n    }\r\n}\r\n\r\nexport class SelectForExtractAction implements Action {\r\n    readonly type = SELECT_FOR_EXTRACT;\r\n\r\n    constructor(public payload: GobiiFileItem) {\r\n    }\r\n}\r\n\r\nexport class DeSelectForExtractAction implements Action {\r\n    readonly type = DESELECT_FOR_EXTRACT;\r\n\r\n    constructor(public payload: GobiiFileItem) {\r\n    }\r\n}\r\n\r\n/**\r\n * Export a type alias of all actions in this action group\r\n * so that reducers can easily compose action types\r\n */\r\nexport type All\r\n    = LoadAction\r\n    | SelectForExtractAction\r\n    | DeSelectForExtractAction;\r\n````\r\n\r\nThe reducer:\r\n\r\n````import {createSelector} from 'reselect';\r\nimport * as gobiiFileItem from '../actions/fileitem';\r\nimport {GobiiFileItem} from \"../../model/gobii-file-item\";\r\nimport * as gobiiFileItemAction from \"../actions/fileitem\";\r\n\r\n\r\nexport interface State {\r\n    fileItemUniqueIdsSelected: string[];\r\n    fileItems: GobiiFileItem[] ;\r\n};\r\n\r\nexport const initialState: State = {\r\n    fileItemUniqueIdsSelected: [],\r\n    fileItems: [],\r\n};\r\n\r\nexport function reducer(state: State = initialState, action: gobiiFileItemAction.All): State {\r\n\r\n    let returnVal: State = state;\r\n\r\n    switch (action.type) {\r\n\r\n        case gobiiFileItemAction.LOAD: {\r\n            const gobiiFileItemsPayload = action.payload;\r\n\r\n            const newGobiiFileItems = gobiiFileItemsPayload.filter(newItem =>\r\n                state\r\n                    .fileItems\r\n                    .filter(stateItem =>\r\n                        stateItem.getExtractorItemType() != newItem.getExtractorItemType() &&\r\n                        stateItem.getEntityType() != newItem.getEntityType() &&\r\n                        stateItem.getEntitySubType() != newItem.getEntitySubType() &&\r\n                        stateItem.getItemId() != newItem.getItemId()\r\n                    )\r\n            );\r\n\r\n            returnVal = {\r\n                fileItems: Object.assign({}, state.fileItems, newGobiiFileItems),\r\n                fileItemUniqueIdsSelected: state.fileItemUniqueIdsSelected\r\n            };\r\n        } // LOAD\r\n\r\n        case gobiiFileItemAction.SELECT_FOR_EXTRACT: {\r\n            //here's where it breaks\r\n            const gobiiFileItemPayload:GobiiFileItem = action.payload;\r\n\r\n\r\n\r\n\r\n        }\r\n\r\n    } // switch()\r\n\r\n    return returnVal;\r\n}\r\n\r\nexport const getFileItems = (state: State) => state.fileItems;\r\n\r\nexport const getUniqueIds = (state: State) => state.fileItems.map(fileItem => fileItem.getFileItemUniqueId());\r\n\r\nexport const getSelectedUniqueIds = (state: State) => state.fileItemUniqueIdsSelected;\r\n\r\nexport const getSelected = createSelector(getFileItems, getSelectedUniqueIds, (fileItems, selectedUniqueIds) => {\r\n    return fileItems.filter(fileItem => {\r\n        selectedUniqueIds.filter(uniqueId => fileItem.getFileItemUniqueId() === uniqueId)\r\n    });\r\n});\r\n\r\nexport const getAll = createSelector(getFileItems, getUniqueIds, (entities, ids) => {\r\n    return ids.map(id => entities[id]);\r\n});\r\n````\r\n\r\nMy package.json: \r\n\r\n````{\r\n  \"name\": \"gobii-web\",\r\n  \"version\": \"0.1.0-SNAPSHOT\",\r\n  \"description\": \"gobii-web extractor build\",\r\n  \"dependencies\": {\r\n    \"@angular/common\": \"4.2.4\",\r\n    \"@angular/compiler\": \"4.2.4\",\r\n    \"@angular/language-service\": \"4.2.4\",\r\n    \"@angular/core\": \"4.2.4\",\r\n    \"@angular/http\": \"4.2.4\",\r\n    \"@angular/platform-browser\": \"4.2.4\",\r\n    \"@angular/platform-browser-dynamic\": \"4.2.4\",\r\n    \"@angular/router\": \"4.2.4\",\r\n    \"@angular/tsc-wrapped\": \"4.2.4\",\r\n    \"@angular/forms\": \"4.2.4\",\r\n    \"@angular/animations\": \"4.2.4\",\r\n    \"core-js\": \"^2.4.1\",\r\n    \"es6-promise\": \"^3.0.2\",\r\n    \"es6-shim\": \"^0.35.0\",\r\n    \"ng2-file-upload\": \"^1.2.1\",\r\n    \"ng2-bootstrap\": \"1.6.3\",\r\n    \"reflect-metadata\": \"^0.1.8\",\r\n    \"rxjs\": \"5.4.2\",\r\n    \"systemjs\": \"^0.19.8\",\r\n    \"zone.js\": \"^0.8.4\",\r\n    \"primeng\": \"4.1.0-rc.2\",\r\n    \"font-awesome\": \"4.7.0\",\r\n    \"bootswatch\": \"3.3.7\",\r\n    \"@ngrx/db\": \"^2.0.2\",\r\n    \"@ngrx/effects\": \"4.0.2\",\r\n    \"@ngrx/router-store\": \"4.0.2\",\r\n    \"@ngrx/store\": \"4.0.2\",\r\n    \"@ngrx/store-devtools\": \"4.0.0\",\r\n    \"reselect\": \"^3.0.1\"\r\n  },\r\n  \"devDependencies\": {\r\n    \"grunt\": \"~0.4.1\",\r\n    \"grunt-ts\": \"~5.3.2\",\r\n    \"grunt-contrib-clean\": \"~0.5.0\",\r\n    \"grunt-contrib-jasmine\": \"~0.5.2\",\r\n    \"grunt-contrib-yuidoc\": \"~0.5.0\",\r\n    \"grunt-template-jasmine-istanbul\": \"~0.2.5\",\r\n    \"grunt-template-jasmine-requirejs\": \"~0.1.7\",\r\n    \"grunt-contrib-uglify\": \"~0.2.5\",\r\n    \"concurrently\": \"^3.1.0\",\r\n    \"lite-server\": \"^2.1.0\",\r\n    \"typescript\": \"2.4.1\",\r\n    \"typings\": \"^0.6.8\",\r\n    \"bootstrap\": \"^3.3.6\"\r\n  },\r\n  \"scripts\": {\r\n    \"postinstall\": \"typings install\",\r\n    \"typings\": \"typings\"\r\n  }\r\n}\r\n````\r\n\r\nMy tsconfig: \r\n\r\n````{\r\n  \"compilerOptions\": {\r\n    \"target\": \"es5\",\r\n    \"module\": \"system\",\r\n    \"moduleResolution\": \"node\",\r\n    \"sourceMap\": true,\r\n    \"emitDecoratorMetadata\": true,\r\n    \"experimentalDecorators\": true,\r\n    \"removeComments\": false,\r\n    \"noImplicitAny\": false //,\r\n//    \"sourceRoot\" : \"C:/phil-source/IntelliJ/gobiiproject/gobii-web/src/main/webapp/js/gobii_modules\"\r\n  },\r\n  \"exclude\": [\r\n    \"node_modules\",\r\n    \"typings/main\",\r\n    \"typings/main.d.ts\",\r\n    \"target\"\r\n  ]\r\n}\r\n````\r\n\r\nThanks I appreciate any help!\r\n--Phil\r\n\r\n\r\n"}}
{"actor":{"display_login":"philipglaser"}}