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

Projects
None yet
10 participants
@HerringtonDarkholme
Member

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 some commits Feb 26, 2017

Allow functions in 'methods' & 'computed' to view themselves, as well…
… as members from 'data' and the Vue instance.
Merge remote-tracking branch 'upstream/dev' into accurateVueTypes
Conflicts:
	types/options.d.ts
	types/test/options-test.ts
	types/test/vue-test.ts
	types/vue.d.ts
[release] weex-vue-framework@2.4.2-weex.1 (#6196)
* build(release weex): ignore the file path of entries

* [release] weex-vue-framework@2.4.2-weex.1

DanielRosenwasser and others added some commits Sep 11, 2017

Merge pull request #1 from DanielRosenwasser/simplifyCreateElement
Simplify 'CreateElement', remove potential error in 'AsyncComponent' …

@vuejs vuejs deleted a comment from RekcuFrehtom Sep 14, 2017

@yyx990803

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Sep 14, 2017

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@yyx990803
Member

yyx990803 commented Sep 14, 2017

@yyx990803 yyx990803 referenced this pull request Sep 14, 2017

Merged

Add Type declaration file #57

@robert-claypool

This comment has been minimized.

Show comment
Hide comment
@robert-claypool

robert-claypool Sep 14, 2017

@yyx990803, looks good, two typos:

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

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

This comment has been minimized.

Show comment
Hide comment
@yyx990803

yyx990803 Sep 14, 2017

Member

@robert-claypool thanks, fixed.

Member

yyx990803 commented Sep 14, 2017

@robert-claypool thanks, fixed.

@HerringtonDarkholme

This comment has been minimized.

Show comment
Hide comment
@HerringtonDarkholme

HerringtonDarkholme Sep 15, 2017

Member

@yyx990803 I'm already on slack!

Member

HerringtonDarkholme commented Sep 15, 2017

@yyx990803 I'm already on slack!

@DanielRosenwasser

This comment has been minimized.

Show comment
Hide comment
@DanielRosenwasser

DanielRosenwasser 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.

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?

@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

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.

@HerringtonDarkholme

HerringtonDarkholme Sep 22, 2017

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.

@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.

@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.

@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

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

@dvic dvic referenced this pull request Oct 8, 2017

Closed

Add support for library projects #3

@HerringtonDarkholme HerringtonDarkholme deleted the HerringtonDarkholme:new-type branch Oct 29, 2017

@eshimischi

This comment has been minimized.

Show comment
Hide comment
@eshimischi

eshimischi Nov 3, 2017

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

eshimischi commented Nov 3, 2017

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

@DanielRosenwasser

This comment has been minimized.

Show comment
Hide comment
@DanielRosenwasser

DanielRosenwasser 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.

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