Subscribe on changes!

TSX typecheck failed when component's props is an empty object

avatar
Jul 2nd 2021

Version

3.1.3

Reproduction link

https://github.com/07akioni/vue-tsx-bug

image

Steps to reproduce

Follow the link

What is expected?

No error

What is actually happening?

Error

avatar
Jul 2nd 2021

Is this a regression?

avatar
Jul 2nd 2021

Is this a regression?

Yes. 3.0.10 works without error.

avatar
Jul 7th 2021

/cc @pikax @johnsoncodehk would appreciate some insights into this

avatar
Jul 7th 2021

would appreciate some insights into this

Caused by https://github.com/vuejs/vue-next/pull/3656

I'll work on a fix.

avatar
Jul 7th 2021

Sorry about that. 🙈

Maybe combine [K in keyof O]?: unknown; and [K in OptionalKeys<O>]?: InferPropType<O[K]>; is works.

export declare type ExtractPropTypes<O> = O extends object ? {
    [K in RequiredKeys<O>]: InferPropType<O[K]>;
} & {
    [K in keyof O]?: InferPropType<O[K]>;
} : {
    [K in string]: any;
};
avatar
Aug 5th 2021

In fact, this problem has always existed, I was wondering if I can modify the code here as

- props: PropsOptions & ThisType<void>
+ props: PropsOptions

All the time, The type PropsOptions is deduced as Readonly<ComponentPropsOptions<Data>> related to here

This will cause a lot array properties in $props due to type ComponentPropsOptions

It can be verified by the following code:

// HelloWorld.tsx

import { defineComponent } from "vue";

export const HelloWorld = defineComponent({
  name: "HelloWorld",
  props: {},
  setup() {
    return () => {
      return (
        <div class="hello">
          <h1>hello</h1>
        </div>
      );
    };
  },
});

const helloWorld = new HelloWorld();
type Keys = keyof typeof helloWorld.$props;

// Before modified

// ("length" | "toString" | "toLocaleString" | "concat" | "join" | "slice" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" | "find" | "findIndex" | "entries" | "keys" | "values" | "includes" | "flatMap" | "flat" | DefaultKeys<readonly string[]> | ((() => IterableIterator<never>) & string) | ((() => string) & string) | ((() => string) & string) | ({
//   (...items: ConcatArray<never>[]): never[];
//   (...items: ConcatArray<never>[]): never[];
// } & string) | (((separator?: string | undefined) => string) & string) | (((start?: number | undefined, end?: number | undefined) => never[]) & string) | (((searchElement: never, fromIndex?: number | undefined) => number) & string) | (((searchElement: never, fromIndex?: number | undefined) => number) & string) | ({
//   <S extends never>(predicate: (value: never, index: number, array: readonly never[]) => value is S, thisArg?: any): this is readonly S[];
//   (predicate: (value: never, index: number, array: readonly never[]) => unknown, thisArg?: any): boolean;
// } & string) | (((predicate: (value: never, index: number, array: readonly never[]) => unknown, thisArg?: any) => boolean) & string) | (((callbackfn: (value: never, index: number, array: readonly never[]) => void, thisArg?: any) => void) & string) | ((<U>(callbackfn: (value: never, index: number, array: readonly never[]) => U, thisArg?: any) => U[]) & string) | ({
//   <S extends never>(predicate: (value: never, index: number, array: readonly never[]) => value is S, thisArg?: any): S[];
//   (predicate: (value: never, index: number, array ...


// After modified

// type Keys = keyof VNodeProps | keyof AllowedComponentProps