type-fest icon indicating copy to clipboard operation
type-fest copied to clipboard

DistributedOmit may not need to constraint the second type argument

Open tommytroylin opened this issue 4 months ago • 6 comments

since typescript omit is something like this

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

could we change the constraint extends KeysOfUnion<ObjectType> in DistributedOmit as same ?

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar

tommytroylin avatar Apr 18 '24 14:04 tommytroylin

Why?

sindresorhus avatar Apr 18 '24 15:04 sindresorhus

@sindresorhus

we were build a component wrapper which disallow passing some specific props directly

the Omit in typescript works great until some one come in with a union typed props

here is the demo


import type { DistributedOmit } from 'type-fest';

type DistributedOmitLoose<
  ObjectType,
  KeyType extends keyof any,
> = ObjectType extends unknown ? Omit<ObjectType, KeyType> : never;

type SomeComponentPropsTypeWithControl = {
  onChange: (value: any) => void;
  controllable: true;
};

type SomeComponentPropsTypeWithoutControl = {
  controllable: false;
};

type SomeComponentProps =
  | SomeComponentPropsTypeWithoutControl
  | SomeComponentPropsTypeWithControl;

// works
type Result1 = Omit<SomeComponentProps, 'value'>;


// works and exactly what i want
type Result2 =
  | Omit<SomeComponentPropsTypeWithControl, 'value'>
  | Omit<SomeComponentPropsTypeWithoutControl, 'value'>;

// loose constraint. works. same as Result2
type Result3 = DistributedOmitLoose<SomeComponentProps, 'value'>;

// DistributedOmit from package
// Type '"value"' does not satisfy the constraint 'keyof SomeComponentPropsTypeWithoutControl'
type Result4 = DistributedOmit<SomeComponentProps, 'value'>;

IMO, when omitting properties from a interface, there's no need to check if they were actually exist. That's why TS's Original Omit didn't check the 2nd type argument. (Just my opinion, not checked if it's right)

tommytroylin avatar Apr 19 '24 04:04 tommytroylin

I do agree that it would be nice to support this use-case. One downside is that it then would not be able to auto-complete the key.

sindresorhus avatar Apr 19 '24 05:04 sindresorhus

@henriqueinonhe Thoughts?

sindresorhus avatar Apr 19 '24 05:04 sindresorhus

I have a similar issue with DistributedOmit

The simple following type does not work

type ReplaceKey<T, V> = T extends { key: string } ? DistributedOmit<T, 'key'> & { key: V } : T

I get the following error

TS2344: Type "key" does not satisfy the constraint KeysOfUnion<T>

Nr9 avatar Apr 24 '24 14:04 Nr9