Repository: vazco/uniforms (ts)

Issue:
uniforms-antd. SelectField. Typing improvements to provide access to antd native props
Motivation:
Ability to pass native antd props like "showSearch", "optionFilterProp", and others.
It already works. As far as I understand via filterDOMProps. But there are some issues with types.
 
Solution:
I suppose the root issue is of using Omit on the union as Omit looks in such a case only on the intersection of props. I attached a solution that works.

Please have a look. If it makes sense for you, I'll create a PR

![image](https://user-images.githubusercontent.com/3891411/117450975-965c3c80-af4a-11eb-8a20-8f41509fd296.png)


Pull request description:
Improved field type inference (fixes #951).
This PR aims to improve the `Override` type as suggested in https://github.com/vazco/uniforms/issues/951#issuecomment-836944631. It revealed a few unnecessary props in the `omit` call as well as some other quirks of `SelectField` in `uniforms-material`.

If possible, @aburtsev, please do check this code.

Patch:
diff --git a/packages/uniforms-material/src/SelectField.tsx b/packages/uniforms-material/src/SelectField.tsx
index 696b1a3d..79d31495 100644
--- a/packages/uniforms-material/src/SelectField.tsx
+++ b/packages/uniforms-material/src/SelectField.tsx
@@ -18,10 +18,8 @@ import wrapField from './wrapField';
 type SelectFieldCommonProps = {
   allowedValues?: string[];
   appearance?: 'checkbox' | 'switch';
-  checkboxes?: boolean;
   disableItem?: (value: string) => boolean;
   inputRef?: Ref<HTMLButtonElement>;
-  native?: boolean;
   required?: boolean;
   transform?: (value: string) => string;
 };
@@ -29,25 +27,25 @@ type SelectFieldCommonProps = {
 type CheckboxesProps = FieldProps<
   string | string[],
   CheckboxProps | SwitchProps,
-  {
+  SelectFieldCommonProps & {
     checkboxes: true;
     legend?: string;
-    native: false;
+    variant?: undefined;
   }
 >;
 
 type SelectProps = FieldProps<
   string | string[],
-  TextFieldProps & MaterialSelectProps,
-  {
+  MaterialSelectProps & TextFieldProps,
+  SelectFieldCommonProps & {
     checkboxes?: false;
     labelProps?: object;
-    textFieldProps: Omit<TextFieldProps, 'value'>;
+    native?: boolean;
+    textFieldProps?: Omit<TextFieldProps, 'value'>;
   }
 >;
 
-export type SelectFieldProps = (CheckboxesProps | SelectProps) &
-  SelectFieldCommonProps;
+export type SelectFieldProps = CheckboxesProps | SelectProps;
 
 const base64: typeof btoa =
   typeof btoa === 'undefined'
@@ -77,14 +75,10 @@ function Select(props: SelectFieldProps) {
     const appearance = props.appearance ?? 'checkbox';
     const SelectionControl = appearance === 'checkbox' ? Checkbox : Switch;
     const filteredProps = omit(filterDOMProps(props), [
-      'checkboxes',
-      'disableItem',
-      'fullWidth',
-      'helperText',
+      'checkboxes' as never,
+      'disableItem' as never,
       'id',
-      'margin',
-      'textFieldProps',
-      'variant',
+      'inputRef',
     ]);
 
     const children =
diff --git a/packages/uniforms/src/types.ts b/packages/uniforms/src/types.ts
index 1cf60911..07e6ebba 100644
--- a/packages/uniforms/src/types.ts
+++ b/packages/uniforms/src/types.ts
@@ -73,7 +73,7 @@ export type HTMLFieldProps<Value, Element, Extension = object> = FieldProps<
 export type ModelTransformMode = 'form' | 'submit' | 'validate';
 
 /** @internal */
-export type Override<T, U> = U & Omit<T, keyof U>;
+export type Override<T, U> = T extends any ? U & Omit<T, keyof U> : never;
 
 export type ValidateMode = 'onChange' | 'onChangeAfterSubmit' | 'onSubmit';
 


Test patch:
diff --git a/packages/uniforms-antd/__tests__/SelectField.tsx b/packages/uniforms-antd/__tests__/SelectField.tsx
index 65d175dd..c07cc2db 100644
--- a/packages/uniforms-antd/__tests__/SelectField.tsx
+++ b/packages/uniforms-antd/__tests__/SelectField.tsx
@@ -388,7 +388,7 @@ test('<SelectField checkboxes> - renders a set of checkboxes with correct option
     <SelectField
       checkboxes
       name="x"
-      transform={(x: string) => x.toUpperCase()}
+      transform={(x: unknown) => String(x).toUpperCase()}
     />
   );
   const wrapper = mount(
diff --git a/packages/uniforms-material/__tests__/SelectField.tsx b/packages/uniforms-material/__tests__/SelectField.tsx
index 8cf70494..49283379 100644
--- a/packages/uniforms-material/__tests__/SelectField.tsx
+++ b/packages/uniforms-material/__tests__/SelectField.tsx
@@ -308,7 +308,6 @@ test('<SelectField> - disabled items (options) based on predicate', () => {
 
 test('<SelectField> - renders with correct classnames', () => {
   const wrapper = mount(
-    // @ts-expect-error Fix SelectFieldProps.
     <SelectField name="x" textFieldProps={{ className: 'select-class' }} />,
     createContext({ x: { type: String, allowedValues: ['a', 'b'] } }),
   );