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

TypeScript: add Props type to component constructor #6901

Open
wonderful-panda opened this issue Oct 24, 2017 · 9 comments
Open

TypeScript: add Props type to component constructor #6901

wonderful-panda opened this issue Oct 24, 2017 · 9 comments

Comments

@wonderful-panda
Copy link

What problem does this feature solve?

It would be useful if we can infer Props type from component (ExtendedVue).

For example, we can write type safe wrapper of CreateElement with it (or improve interface of CreateElement directly).

function renderComponent<Props>(
        h: CreateElement,
        component: ExtendedVue<Vue, {}, {}, {}, Props>,
        data: VNodeData & { props: Partial<Props> },
        children?: VNodeChildren): VNode {
  return h(component, data, children);
}

const MyComponent = Vue.extend({
  props: { foo: String },
  render(h) { return h("div", this.foo) };
});

const Parent = Vue.extend({
  render(h) {
    return renderComponent(h, MyComponent, { props: { foo: 0 } }); // error: type of property 'foo' are imcompatible
  }
});

What does the proposed API look like?

Now, ExtendedVue<Vue, {}, {}, {}, { foo: string }> and ExtendedVue<Vue, {}, {}, { foo: string }, {}> generate same type.

This means we can't determine Props type from ExtendedVue object.

I think, easiest (and most reasonable) way to achieve this is adding types to $props and $data

- export type CombinedVueInstance<Instance extends Vue, Data, Methods, Computed, Props> = Instance & Data & Methods & Computed & Props;
+ export type CombinedVueInstance<Instance extends Vue, Data, Methods, Computed, Props> = Instance & Data & Methods & Computed & Props & { $data: Data, $props: Props };
@HerringtonDarkholme
Copy link
Member

HerringtonDarkholme commented Oct 24, 2017

Actually we can do better here. By changing Vue to a generic type constructor (with default so no breaking change), we can encode Vue.extend to return a constructor with $props and $data typed. Plus, typed JSX will be enabled.

But this will make our complex typing file more complicated. Let's first make Vue2.5 stable and wait for more feedback.

If you like this idea, please vote by emoji!

cc @ktsn @yyx990803 @octref @kaorun343

@wonderful-panda
Copy link
Author

Sounds nice.
Above all, it would be very nice if vue supports typed JSX by default.
(I have a small library to add types to component for typed JSX. AAMOF, this issue comes from it.)

BTW, current typing loses the information about each props are required or optional, which is necessary for typed JSX.

@HerringtonDarkholme HerringtonDarkholme changed the title TypeScript: Make enable to infer Props type from component TypeScript: add Props type to component constructor Oct 24, 2017
@HerringtonDarkholme
Copy link
Member

current typing loses the information about each props are required or optional

Fairly I don't think we can make a typing for current API, at least current TS' type system does not support it.

Example

@blake-newman
Copy link
Member

blake-newman commented Oct 24, 2017

I have been using library mentioned, I think first step we can do is make all props optional when using TSX with Partial, unless passing a declared interface.

It will then be an enhancement when TS does support it. I think we should also create a TS issue to make awareness of this requirement linking back to this issue.

I do believe we should support typed TSX out of the box with props inferred. Unfortunately but ultimately great Vue API also has more custom attributes to TSX such as scoped slots and events that we need to cater for. So interfaces will still be required as far as I can see. However where possible we should reduce the needed typing especially where duplication occurs, such as prop definitions.

@wonderful-panda
Copy link
Author

How about an approach like below ?

image

(It works, but type definitions will become more complicated ...)

@blake-newman
Copy link
Member

@wonderful-panda we could form requiredProps from props object no?

@wonderful-panda
Copy link
Author

@blake-newman
It may be impossible to obtain requiredProps from props at compile time.

In above example, type of repuiredProps is ("foo"|"bar")[]

@blake-newman
Copy link
Member

Yes sorry forgot about that

@JonasMatos0
Copy link

Hello,

What's the current state of this issue?
I'm taking a look on these really old GFI tickets.
I can try to help, just need some details about how to proceed.

Thanks in advance.

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

5 participants