You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Pick<Type, GenericParameter> throws new errors for attempting to access properties #28719
src/example.ts:17:15 - error TS2339: Property 'a' does not exist on type 'Pick<Foo, K>'.
17 if (state.a) {
~
src/example.ts:19:15 - error TS2339: Property 'b' does not exist on type 'Pick<Foo, K>'.
19 state.b = true;
Playground Link:
Related Issues:
Possibly related to #28647, but I'm unsure.
That's plausible. Currently, the function in question in our code base is trying to pass the parameter on to React's setState, whose types have the following comment:
// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257// Also, the ` | S` allows intellisense to not be dumbisensesetState<KextendskeyofS>(state: ((prevState: Readonly<S>,props: P)=>(Pick<S,K>|S|null))|(Pick<S,K>|S|null),callback?: ()=>void): void;
In our actual usage, we're seeing if a property exists on the parameter; if so, we add more properties before calling setState:
privatesetStateBasedOnMode=<KextendskeyofDateSelectorState>(state: Pick<DateSelectorState,K>)=>{if(state.currentSelectorMode){// update the shownViewStates if the currentSelectorMode is changedletshownViewStates=this.getShownViewState(state.currentSelectorMode);state.showEndTime=shownViewStates.showEndTime;state.showDuration=shownViewStates.showDuration;state.showEndDate=shownViewStates.showEndDate;state.showTimeOrDuration=shownViewStates.showTimeOrDuration;state.showTimeZones=shownViewStates.showTimeZones;}this.setState(state);};
Is this something that would simply need to be fixed in @types/react? And/or is there a better method on our side?
Anders Hejlsberg (@ahejlsberg) we saw that strange pattern when we reviewed the rwc baselines for your change, if I recall. Did we decide what the better way to write that in a typesafe way was? Off the cuff I'd say a spread'd be better, personally.
Off the cuff I'd say a spread'd be better, personally.
Agreed. A particularly troublesome aspect of the code example above is that it mutates the state input object. That could lead to some very subtle issues if a caller were to use a shared object instead of an object literal. With a spread you're guaranteed that the combined object is freshly allocated and not aliased.
Spread where, exactly? To get it to work, I still seem to have to type-cast it:
privatesetStateBasedOnMode=<KextendskeyofDateSelectorState>(state: Pick<DateSelectorState,K>)=>{if((stateasDateSelectorState).currentSelectorMode){// update the shownViewStates if the currentSelectorMode is changedletshownViewStates=this.getShownViewState((stateasDateSelectorState).currentSelectorMode);this.setState({
...state,showEndTime: shownViewStates.showEndTime,showDuration: shownViewStates.showDuration,showEndDate: shownViewStates.showEndDate,showTimeOrDuration: shownViewStates.showTimeOrDuration,showTimeZones: shownViewStates.showTimeZones,});}else{this.setState(state);}};
privatesetStateBasedOnMode=(state: Partial<DateSelectorState>)=>{if(state.currentSelectorMode){// update the shownViewStates if the currentSelectorMode is changedletshownViewStates=this.getShownViewState(state.currentSelectorMode);this.setState({
...state,showEndTime: shownViewStates.showEndTime,showDuration: shownViewStates.showDuration,showEndDate: shownViewStates.showEndDate,showTimeOrDuration: shownViewStates.showTimeOrDuration,showTimeZones: shownViewStates.showTimeZones,});}else{this.setState(state);}};
Also ran into this today when upgrading typescript. Similar use-case where I'm accepting an argument that gets passed to React's setState with potentially additional data added depending on which fields are passed in.
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.
Activity
jack-williams commentedon Nov 28, 2018
This implementation seems unsound given the follow instantiation.
MLoughry commentedon Nov 28, 2018
That's plausible. Currently, the function in question in our code base is trying to pass the parameter on to React's
setState, whose types have the following comment:In our actual usage, we're seeing if a property exists on the parameter; if so, we add more properties before calling setState:
Is this something that would simply need to be fixed in
@types/react? And/or is there a better method on our side?weswigham commentedon Nov 29, 2018
Anders Hejlsberg (@ahejlsberg) we saw that strange pattern when we reviewed the rwc baselines for your change, if I recall. Did we decide what the better way to write that in a typesafe way was? Off the cuff I'd say a spread'd be better, personally.
ahejlsberg commentedon Nov 29, 2018
Agreed. A particularly troublesome aspect of the code example above is that it mutates the
stateinput object. That could lead to some very subtle issues if a caller were to use a shared object instead of an object literal. With a spread you're guaranteed that the combined object is freshly allocated and not aliased.MLoughry commentedon Nov 29, 2018
Spread where, exactly? To get it to work, I still seem to have to type-cast it:
weswigham commentedon Nov 29, 2018
?
MLoughry commentedon Nov 29, 2018
Unfortunately, no. 😔
TLadd commentedon Jan 9, 2019
Also ran into this today when upgrading typescript. Similar use-case where I'm accepting an argument that gets passed to React's setState with potentially additional data added depending on which fields are passed in.
typescript-bot commentedon Jul 13, 2019
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.