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
I am trying to write a higher-order function that applies default parameters to a function that has "named parameters". Currently I have the following code:
typeOmit<Aextendsobject,Kextendsstring|number|symbol>=Pick<A,Exclude<keyofA,K>>;typeDiff<Aextendsobject,KextendskeyofA>=Omit<A,K>&Partial<Pick<A,K>>;constwithDefaults=<Paramsextendsobject,DefaultParamsKeysextendskeyofParams,Result>(fn: (params: Params)=>Result,defaultParams: Pick<Params,DefaultParamsKeys>,)=>(inputParams: Diff<Params,DefaultParamsKeys>): Result=>// Cast necessary to workaround https://github.com/Microsoft/TypeScript/issues/28748fn(({
...defaultParams,
...inputParams,}asunknown)asParams);// Example{typeParams={a: string;b: number;c?: string;};const_fn=(params: Params)=>{};withDefaults(_fn,{b: '1',// expect error: defaults are type checked});constdefaults={b: 1,c: 'foo'};constfn=withDefaults(_fn,defaults);fn({});// expect error: non-defaults are requiredfn({a: 1});// expect error: non-defaults are type checkedfn({a: 'foo'});// defaults may be emittedfn({a: 'foo',b: 2});// defaults may be overriddenfn({a: 'foo',b: ''});// expect error: defaults are type checked}
This works, but I'm wondering if it could be made easier.
If I understand correctly, we want to enforce that the defaultParams parameter is a supertype of the Params generic.
I'm achieving this in a semi-roundabout way using extends keyof and Pick:
// Constrain `defaultParams` to supertype of `Params`constfn=<Paramsextendsobject,DefaultParamsKeysextendskeyofParams>(params: Params,defaultParams: Pick<Params,DefaultParamsKeys>,)=>{defaultParams=params;declareletparamsKey: keyofParams;declareletdefaultParamsKey: DefaultParamsKeys;paramsKey=defaultParamsKey}
I had expected to achieve the same effect using extends Partial<Params>, but it seems not:
constfn2=<Paramsextendsobject,DefaultParamsextendsPartial<Params>>(params: Params,defaultParams: DefaultParams,)=>{// Type 'Params' is not assignable to type 'DefaultParams'.defaultParams=params;declareletparamsKey: keyofParams;declareletdefaultParamsKey: keyofDefaultParams;// Type 'keyof DefaultParams' is not assignable to type 'keyof Params'.paramsKey=defaultParamsKey}
Is this a bug or intended behaviour?
Ideally TypeScript would have syntax to make this easier:
I believe syntax like this was initially suggested in #9252 and #7265, although Partial types claimed to be the solution, even though I can't get it to work 🤔
Note I may have got the wrong idea about defaultParams needing to be a supertype of Params? 🤔
because DefaultParams can sometimes be a subtype (more specific) of Params. E.g. from the example above, when providing defaults for an optional key c, DefaultParams will be { c: string; } whereas Params will be { c?: string; }.
I'm now thinking that DefaultParams should be neither a supertype of subtype of Params. It is just a picked version of Params? In which case, my solution above would be the way to go.
TypeScript Version: 3.2.2
Search Terms: supertype constraint extends partial
Code
I am trying to write a higher-order function that applies default parameters to a function that has "named parameters". Currently I have the following code:
This works, but I'm wondering if it could be made easier.
If I understand correctly, we want to enforce that the
defaultParams
parameter is a supertype of theParams
generic.I'm achieving this in a semi-roundabout way using
extends keyof
andPick
:I had expected to achieve the same effect using
extends Partial<Params>
, but it seems not:Is this a bug or intended behaviour?
Ideally TypeScript would have syntax to make this easier:
I believe syntax like this was initially suggested in #9252 and #7265, although
Partial
types claimed to be the solution, even though I can't get it to work 🤔Note I may have got the wrong idea about
defaultParams
needing to be a supertype ofParams
? 🤔Potentially related to #14520 also.
The text was updated successfully, but these errors were encountered: