vue-property-decorator icon indicating copy to clipboard operation
vue-property-decorator copied to clipboard

"type" in @Model / @Prop should allow "null"

Open whitetrefoil opened this issue 6 years ago • 1 comments

@Prop({ type: null, required: true }) myProp!: any;

This will become: image

This is just a type-checking problem, the code can already run well functionally.

This is not the same as #35 which is not required: true.

Real world meaning:

  1. A prop is required but undefined and null should be valid.
  2. Manually override the bad type guessing from reflect-metadata.
  3. Currently when with reflect-metadata, even a custom validator has been set, propType still get checked by a guessed type. The only solution I found is setting "type" to null.

whitetrefoil avatar Jun 12 '19 03:06 whitetrefoil

I'm using the following code (saved as vue-property-decorator.d.ts) as a workaround to overwrite the definition of Prop to allow type: null.

FYI.

import { PropOptions as BasePropOptions, PropType } from 'vue';
import { VueDecorator } from 'vue-class-component';
import { Constructor } from 'vue-property-decorator';

// Overwrite the definition of 'Prop' to allow 'type: null'.
//
// This is required for a complex type with reflect-metadata.
// For example
//
//   @Prop()
//   readonly foo: string | null;
//
// with relfect-metadata produce
//
//   foo: {
//     type: String
//   }
//
// and [Vue warn]: Invalid prop: type check failedc for "foo". Expected String, got Null
// will be shown when 'null' is passed to the 'foo'.
//
// With this hack, simpli use 'type: null' to prevent that warning like
//
//   @Prop({ type: null })
//   readonly foo: string | null;
//
// Or better to
//
//   @Prop({
//     type: null,
//     validator(v) {
//       return v == null || typeof v === 'string';
//     },
//   })
//   readonly foo: string | null;
//
// Ref https://github.com/kaorun343/vue-property-decorator/issues/213
declare module 'vue-property-decorator' {
  type PropOptions<T = any> = Omit<BasePropOptions<T>, 'type'> & {
    type?: PropType<T> | null;
  };
  export function Prop(
    options?: PropOptions | Constructor[] | Constructor,
  ): VueDecorator;
}

lambdalisue avatar Jul 04 '19 06:07 lambdalisue