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

Further improve Vue type declarations for canonical usage #6391

Merged
merged 56 commits into from Oct 6, 2017

Conversation

@HerringtonDarkholme
Copy link
Member

@HerringtonDarkholme HerringtonDarkholme commented Aug 17, 2017

This pull request supersedes #5887 .

Key improvements:

  1. More backward compatible via generic default
  2. Props type inference

@ktsn @kaorun343 @DanielRosenwasser Your reviews or suggestions are welcome!


This section provides more background for other reviewers/readers.

Vue + TS users currently need helper library like vue-component-class to provide alternative API for TypeScript. Alternative API uses code pattern that TypeScript recognizes, but it splits Vue community.

Thankfully, TypeScript introduces ThisType which can greatly improve Vue's canonical API. This PR introduces ThisType to Vue's official typing.

More importantly, this improvement also benefits JavaScript users! VSCode users or Vue-language-server users exploits TypeScript compiler to provide editor services for JavaScript. Thus the typing improvement can help JavaScript completion more intelligent.

Goal:

  1. Provide good enough completions for both JS users and new TS users (if they use canonical API).
  2. Don't break existing TS libraries or projects. Or, make breaking minimal.

Non Goal:

  1. This PR won't provide 100% typing precision or use case coverage. Such typing would be too prohibitive for both maintainers and users to reason.
  2. Checking errors in JS isn't kept in mind. So changing existing JS to TS will cause errors.

Known limitations:

  1. new Vue() wouldn't return a type with props type. This is caused by compiler limitations.
  2. Props typing uses a hacky trick.
  3. returning properties on this might trigger cyclic error, manual annotation is needed.
  4. Prop type's union type declaration like oneProp: [String, User] might not work without manual annotation.

Next step:
Since we already has a canonical Vue API in TS, next we can ship tsx support in the official repo.

yyx990803 and others added 30 commits Feb 26, 2017
… as members from 'data' and the Vue instance.
Conflicts:
	types/options.d.ts
	types/test/options-test.ts
	types/test/vue-test.ts
	types/vue.d.ts
Conflicts:
	package.json
* build(release weex): ignore the file path of entries

* [release] weex-vue-framework@2.4.2-weex.1
Conflicts:
	types/vue.d.ts
Simplify 'CreateElement', remove potential error in 'AsyncComponent' …
@vuejs vuejs deleted a comment from RekcuFrehtom Sep 14, 2017
@yyx990803
Copy link
Member

@yyx990803 yyx990803 commented Sep 14, 2017

@HerringtonDarkholme are you on slack? Can you give an email address so I can invite you to the team slack? (maybe via Twitter DM)

@yyx990803
Copy link
Member

@yyx990803 yyx990803 commented Sep 14, 2017

@robert-claypool
Copy link

@robert-claypool robert-claypool commented Sep 14, 2017

@yyx990803, looks good, two typos:

  • "Daniel Rosenwasser from the TypeScript started" --> missing word?
  • "in anyway; per semver" --> any way
@yyx990803
Copy link
Member

@yyx990803 yyx990803 commented Sep 14, 2017

@robert-claypool thanks, fixed.

@HerringtonDarkholme
Copy link
Member Author

@HerringtonDarkholme HerringtonDarkholme commented Sep 15, 2017

@yyx990803 I'm already on slack!

@DanielRosenwasser
Copy link

@DanielRosenwasser DanielRosenwasser commented Sep 15, 2017

I will try to give some deeper feedback later, but

  • "So that we" doesn't flow will into the items listed
  • The features we added that enabled this support were chiefly in 2.1 to 2.3.
extend<PropNames extends string = never>(definition: FunctionalComponentOptions<Record<PropNames, any>, PropNames[]>): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>>;
extend<Props>(definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;
extend<Data, Methods, Computed, PropNames extends string>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, any>>;
extend<Data, Methods, Computed, Props>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;

This comment has been minimized.

@DanielRosenwasser

DanielRosenwasser Sep 21, 2017

Having tried this out, while Props inference is great, I think there will be cases where someone will want to write an interface for props and then let Data, Methods, and Computed be inferred on their own, and then let

Maybe we should reorder this so that Props comes first? something like

extend<Props = Record<PropNames, any>, PropNames extends string = never, Data = {}, Methods = {}, Computed = {}>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Props>;
extend<Props = {}, Data = {}, Methods = {}, Computed = {}>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;

What do you think @HerringtonDarkholme?

This comment has been minimized.

@HerringtonDarkholme

HerringtonDarkholme Sep 22, 2017
Author Member

I wonder if inferring default generic parameter is available in current TS. microsoft/TypeScript#14400 or this comment microsoft/TypeScript#13487 (comment)

So users have to annotate all the type parameters as long as they want to specify at least one parameter.

This comment has been minimized.

@DanielRosenwasser

DanielRosenwasser Sep 28, 2017

Unfortunately we haven't yet implemented that. This isn't a blocker though.

This comment has been minimized.

@yyx990803

yyx990803 Oct 6, 2017
Member

I'm merging this in preparation for 2.5 release. We can improve upon this in a separate PR later.

This comment has been minimized.

@zigomir

zigomir Oct 13, 2017
Contributor

We were using this pattern below

interface AppComponent extends Store, Vue {
  // Additional typed props besides ones defined on Store here
}

export default {
// ...
} as ComponentOptions<AppComponent>

but it looks like this isn't possible with Vue 2.5 no more. Is there another way to type your props now? Possible workaround is to wrap props inside computed property with added type, but this isn't really elegant.

@yyx990803 yyx990803 merged commit db138e2 into vuejs:dev Oct 6, 2017
5 checks passed
5 checks passed
ci/circleci: install Your tests passed on CircleCI!
Details
ci/circleci: lint-flow-types Your tests passed on CircleCI!
Details
ci/circleci: test-cover Your tests passed on CircleCI!
Details
ci/circleci: test-e2e Your tests passed on CircleCI!
Details
ci/circleci: test-ssr-weex Your tests passed on CircleCI!
Details
@HerringtonDarkholme HerringtonDarkholme deleted the HerringtonDarkholme:new-type branch Oct 29, 2017
@eshimischi
Copy link

@eshimischi eshimischi commented Nov 3, 2017

@yyx990803 @HerringtonDarkholme @DanielRosenwasser any changes to Vue typings due to TS 2.6 release?

@DanielRosenwasser
Copy link

@DanielRosenwasser DanielRosenwasser commented Nov 3, 2017

@eshimischi if you're having any specific problems with the type declarations given TypeScript 2.6, I'd suggest you file a separate issue.

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

Successfully merging this pull request may close these issues.

None yet

10 participants
You can’t perform that action at this time.