Uh oh!
There was an error while loading. Please reload this page.
Spread type - #13288
Conversation
Nathan Shively-Sanders (sandersn)
commented
Jan 4, 2017
Anders Hejlsberg (@ahejlsberg) this is the PR I was talking about. |
`spread(T)` is also allowed, for unary spreads
| } | ||
| const type = checkExpression((memberDecl as SpreadAssignment).expression); | ||
| if (!isValidSpreadType(type)) { | ||
| if (type.flags & (TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.BooleanLike | TypeFlags.EnumLike | TypeFlags.ESSymbol)) { |
There was a problem hiding this comment.
should just change the definition of isValidSpreadType
Previously it would only get the top two.
I missed this in the object-spread PR.
David Xiao (dxiao)
commented
May 2, 2017
Any chance this can merge in sometime for 2.3.3? Proving kinda annoying to deal with... |
Chris Schmitz (ccschmitz)
commented
May 4, 2017
Same for us, David Xiao (@dxiao). We get a pile of new errors on 2.3. Holding out on the upgrade because of it. We are holding out on the upgrade in hopes a fix like this makes it out in a patch release. |
Mohamed Hegazy (mhegazy)
commented
May 4, 2017
This is a new feature, and will not be added in a patch release. |
I think people who were already using the spread operator in TSX would argue, purely from a consumer of TypeScript perspective, this is not a new feature, but a regression. If it's not going to make it into a patch release, then we're waiting until at least 2.4, which is how far off? So anyone who wants to use spread operators in TSX (which is pretty much a requirement for React + react-router) we're going to have to skip 2.3 entirely |
prencher
commented
May 8, 2017
Mohamed Hegazy (@mhegazy) This use case broke with 2.3 from 2.2, even if the behavior may not have been correct prior to 2.3. I would highly urge you to fix it in 2.3, it is a major regression. |
Victor Bianchi (jvbianchi)
commented
Jan 12, 2018
Is this ready for merge? |
Victor Bianchi (@jvbianchi) No. See preceding discussion. |
Nathan Shively-Sanders (@sandersn) Your July 18 comment doesn't address positive extend scenarios, or maybe I'm misunderstanding. If I have Your comment seems to acknowledge the difficulties with assigning properties to completely unknown |
Rob Yoder (@robyoder) what if |
Rob Yoder (robyoder)
commented
Jan 24, 2018
Yeah that's unfortunate. Too bad there's no way to force invariance in certain places. |
Nathan Shively-Sanders (@sandersn) but variance isn't really a holdup, right? TS already fails there: constfunc=<Textends{a: string}>(param: T): T=>{constcloned: T=clone(param);cloned.a="something";returncloned;};interfaceFoo{a: "foo"|"bar";}constdata: Foo={a: "foo"};constdata2: Foo=func(data);// this type checks, but `a` is now "something", not "foo" or "bar" |
Rob Yoder (@robyoder) Good point. What is the scenario you would like to work? Constraining |
Rob Yoder (robyoder)
commented
Jan 24, 2018
Yeah, I'm not using React HOCs atm. In this specific case, I have an object with a default id of 0, and I'm saving it to storage and getting it back with the id set properly. So something like this: constaddEntry=<Textends{id: number}>(entry: T): T=>{constid=entry.id>0 ? entry.id : getTheNextId();constnewEntry={ ...entry, id };returnsaveToStorage(newEntry);// returns newEntry after saving it}And right now that obviously gives me the error |
Dirk-Jan Wassink (DJWassink)
commented
Feb 21, 2018
Just a little headsup for people ending up here. It seems like publicaddSomethingToBar<TextendsIBar>(bar: T): T&{foo: number[]}{returnObject.assign({},bar,{foo: [1,2]});} |
Nicolas Fernandez (burabure)
commented
Apr 2, 2018
any updates on this?, we really need something better than // Cant use spread here because of TS issue, see TypeScript #10727 #13288// tslint:disable-next-line:prefer-object-spreadthis.setState(prevState=>Object.assign({},prevState,newState))... |
Zheeeng (zheeeng)
commented
Apr 9, 2018
expecting on progress. |
I am hitting this issue all the time since I work with immutable objects frequently with Redux. |
Hmm. I am also getting the issue when trying to use generics for React HOCs with spread params. interfaceInjectedProps{readonlyp1: string;readonlyp2: number;}functionhoc<PextendsInjectedProps>(Component: React.ComponentType<P>){// ERROR: Rest types may only be created from object types.return({ p1, p2, ...rest} : P)=><Wrapperp1={p1}p2={p2}><Component{...rest}/></Wrapper>;}Do we have an alternative version for solving the issue? |
Luke Scott (lukescott)
commented
Apr 13, 2018
Besides using Object.assign, you can tack on |
andretshurotshka (goodmind)
commented
Apr 13, 2018
Use this /** * Get all names of properties with types that include undefined. */exporttypeOptionalPropNames<T>={[KinkeyofT]: undefinedextendsT[K] ? K : never}[keyofT];/** * Common properties from L and R with undefined in R[K] replaced by type in L[K] */exporttypeSpreadProps<L,R,KextendskeyofL&keyofR>={[PinK]: L[P]|Exclude<R[P],undefined>};/** * Type of `{ ...L, ...R }` / `Object.assign(L, R)`. */exporttypeSpread<L,R>=/** properties in L that don't exist in R */Pick<L,Exclude<keyofL,keyofR>>/** properties in R with types that exclude undefined */&Pick<R,Exclude<keyofR,OptionalPropNames<R>>>/** properties in R, with types that include undefined, that don't exist in L */&Pick<R,Exclude<OptionalPropNames<R>,keyofL>>/** properties in R, with types that include undefined, that exist in L */&SpreadProps<L,R,OptionalPropNames<R>&keyofL>; |
João Vieira (joaovieira)
commented
Jun 7, 2018
Bump. Where is this going? Still waiting.. 😕 |
original commit in this PR was created as TS was 2.2 it seems that this is simply not a priority :( hey Nathan Shively-Sanders (@sandersn)Anders Hejlsberg (@ahejlsberg), I'm sorry for mentioning you, but it seems that this PR got lost in stream of other issues? Any possibility to see this in |
Marco Ferreira (mfferreira)
commented
Jul 13, 2018
Bump |
Siwat Kaolueng (perjerz)
commented
Aug 10, 2018
any update? |
Ryan Cavanaugh (RyanCavanaugh)
commented
Aug 10, 2018
As everyone can probably tell, this PR didn't get merged and is now painfully out of date. Mapped and conditional types meet a very large proportion of the use cases here. Here's an example of combining two types including exclusion and overwriting: typeType1={x: number,y: number};typeType2={name: string,kind: string,y: string;};typeSpread<T1,T2,TExclude>={[KinExclude<keyofT1,TExclude|keyofT2>]: T1[K]}&{[KinExclude<keyofT2,TExclude>]: T2[K]};typeType3=Spread<Type1,Type2,"name">declareconstt3: Type3;t3.We'd like people bumping/thumbing/pinging this PR to try using these sorts of types in their scenarios to see what other use cases still need to be designed around if we do include an explicit spread type syntax - see the original PR comments for links. Thanks! |

Fixes#10727
Fixes#11100
Follow-up to #11150 — most discussion has already taken place there; this PR just updates the previously-unreleased spread type code.