Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert TSX using TypeScript(ts-loader) #428

Closed
tonitrnel opened this issue Jul 4, 2020 · 6 comments
Closed

Convert TSX using TypeScript(ts-loader) #428

tonitrnel opened this issue Jul 4, 2020 · 6 comments
Assignees

Comments

@tonitrnel
Copy link

Hi, I converted TSX by configuring the jsx and jsxFactory properties of the tsconfig.json file

"jsx": "react",
"jsxFactory": "defineComponent.createElement",

I copied the h function to defineComponent in the following way

import { h, defineComponent } from '@vue/composition-api';
// @ts-ignore
defineComponent.createElement = function createElement(
  element: any,
  props: any,
  ...children: any
) {
  return h(element, props, children);
};

Now TSX conversion is successful, but the top node information is lost, such as id

Here has a simple code example https://github.com/piecego/vue-composition-api-tsx-example.git

Please help me see why, and whether this method can be used instead of babel for conversion?

Thanks!!!

@antfu
Copy link
Member

antfu commented Jul 7, 2020

Change to return h(element, { attrs: props }, children); and it should work. But to do it properly, it may require you to write some logic to sperate props and attrs, etc. You can check the accepting type of h function here: https://github.com/vuejs/vue/blob/8ead9d2a0d4ca686eaf5e35526eff4af1b8c79a7/types/vnode.d.ts#L15-L31

And BTW, that's an interesting usage, and thanks for sharing. If you would like to make it general for people to use (a lib or even just a guide), please let me know! :)

@tonitrnel
Copy link
Author

Ok, I will try to convert the Props that TypeScript gives me to VNodeData.

Now, I'm having a problem with props type, can you help me see ?

The problem manifests as: passing non-existent properties on the component will not raise any errors

References:
TypeScript JSX Doc

Code:
https://github.com/piecego/vue-composition-api-tsx-example/blob/master/src/shims-tsx.d.ts#L28
https://github.com/vuejs/composition-api/blob/master/src/component/componentProxy.ts#L28

Thanks!!!

@tonitrnel
Copy link
Author

Hi. @antfu

I used the weekend time to read the type file of composition-api, found the following problems:

  1. ComponentRenderProxy should not directly merge Vue types

    Location is:

    vue.d.ts#L34

    componentProxy.ts#L40

    Record<string, any> will prevent ts from checking non-existent attributes, Involves $props, $data, and $attrs attributes, I recommend using Omit to exclude it

  2. ExtractFunctionPropType should not return never

    Location is:

    componentProps.ts#L46

    A form like onClick: Function will return undefined

    I recommend return (...args: any[]) => any

  3. Is it necessary for VueProxy to return VueConstructor? It will pollutes existing types. I printed the component defined with defineComponent in the console, But I can't see anything that matches the definition of "VueConstructor".

Also, should JSX.ElementAttributesProperty use $data instead of $props attribute, right?

@tonitrnel
Copy link
Author

Also, there seems to be no definition of refs for SetupContext

@antfu
Copy link
Member

antfu commented Jul 12, 2020

@piecego

Record<string, any> will prevent ts from checking non-existent attributes, Involves $props, $data, and $attrs attributes, I recommend using Omit to exclude it

You are right, I will fix it.

ExtractFunctionPropType should not return never

Nice catch-up, I think we should copy the type from vue-next and test out:
https://github.com/vuejs/vue-next/blob/903e8f697e4377e0ae92e1a6b58777438fba3610/packages/runtime-core/src/componentProps.ts#L78-L94

VueConstructor

It's probably for toolchains/vetur to infer the type.

no definition of refs for SetupContext

This is on purpose, as the refs are not there in Vue 3. We expose it as a temporary workaround, you can found more in the README


Thanks for looking into it and they're pretty helpful!

@tonitrnel
Copy link
Author

It's probably for toolchains/vetur to infer the type.

VueConstructor interface has a new statement, it will invalidate the previous defined type.

Because it returns object & Record<never, any> & Vue, here quote Vue insterface , it is the same as the first problem.

@antfu antfu self-assigned this Jul 14, 2020
antfu added a commit to antfu/composition-api that referenced this issue Jul 18, 2020
antfu added a commit that referenced this issue Jul 18, 2020
* fix(type): fix tying issues in #428

* fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants