Skip to content

Improve Vue type declarations for more canonical usage #5887

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

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5b5a88f
refactor TypeScript typings to use ES style exports
yyx990803 Feb 26, 2017
385a744
Allow functions in 'methods' & 'computed' to view themselves, as well…
DanielRosenwasser Mar 8, 2017
8cd5b9c
Got 'new Vue(...)', 'Vue.extend(...)', and 'Vue.component(...)' working.
DanielRosenwasser Mar 16, 2017
540a38f
Made it so that any 'data' function can only access 'props' and base …
DanielRosenwasser Mar 27, 2017
f34f4f6
Improved defaults, fixed overloads and types for functional component…
DanielRosenwasser Jun 1, 2017
b1f40ce
Condensed declaration of 'watch'.
DanielRosenwasser Jun 1, 2017
355ff75
Added two tests for 'extend'.
DanielRosenwasser Jun 1, 2017
bc54007
.\types\options.d.ts
DanielRosenwasser Jun 1, 2017
e7ea5bb
Updated tests, tighted strictness.
DanielRosenwasser Jun 1, 2017
ebde0b1
Merge remote-tracking branch 'upstream/dev' into accurateVueTypes
DanielRosenwasser Jun 1, 2017
d78d14b
Made the Vue instance non-generic, made readonly, augmented tests.
DanielRosenwasser Jun 14, 2017
fc83771
Make it possible to extend Vue without type arguments.
DanielRosenwasser Jun 14, 2017
a50c838
Removed 'ThisTypedComponentOptions'.
DanielRosenwasser Jun 14, 2017
3c86b10
Merge remote-tracking branch 'upstream/dev' into accurateVueTypes
DanielRosenwasser Jun 14, 2017
33a106c
Upgraded dependency on TypeScript.
DanielRosenwasser Jun 15, 2017
0f586db
Added test by @ktsn.
DanielRosenwasser Jun 15, 2017
1092efe
Removed unnecessary mixin constructors, made 'VueConstructor' generic.
DanielRosenwasser Jun 15, 2017
ebd8c0b
Merge remote-tracking branch 'upstream/dev' into accurateVueTypes
DanielRosenwasser Jun 23, 2017
c628103
[release] weex-vue-framework@2.4.2-weex.1 (#6196)
Hanks10100 Jul 24, 2017
e4a8545
Merge remote-tracking branch 'upstream/dev' into accurateVueTypes
DanielRosenwasser Jul 28, 2017
f7ebfa3
Props -> Record<keyof Props, any>
DanielRosenwasser Aug 16, 2017
bb0ff30
Update TypeScript devDependency.
DanielRosenwasser Aug 16, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Made the Vue instance non-generic, made readonly, augmented tests.
  • Loading branch information
DanielRosenwasser committed Jun 14, 2017
commit d78d14b832b2e42d44bdcb3a3f89d18f8e9845dc
14 changes: 12 additions & 2 deletions types/test/augmentation-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Vue from "../index";

declare module "../vue" {
// add instance property and method
interface Vue<Data, Methods, Computed> {
interface Vue {
$instanceProperty: string;
$instanceMethod(): void;
}
Expand All @@ -22,10 +22,20 @@ declare module "../options" {
}

const vm = new Vue({
props: ["bar"],
data: {
a: true
},
foo: "foo"
methods: {
foo() {
this.a = false;
}
},
computed: {
BAR(): string {
return this.bar.toUpperCase();
}
}
});

vm.$instanceProperty;
Expand Down
4 changes: 2 additions & 2 deletions types/test/vue-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class Test extends Vue<object, object, object> {

// test property reification
$refs: {
vue: Vue<object, object, object, never>,
vue: Vue,
element: HTMLInputElement,
vues: Vue<object, object, object, never>[],
vues: Vue[],
elements: HTMLInputElement[]
}
testReification() {
Expand Down
2 changes: 1 addition & 1 deletion types/vnode.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vue, AnyVue } from "./vue";
import { Vue } from "./vue";

export type ScopedSlot = (props: any) => VNodeChildrenArrayContents | string;

Expand Down
10 changes: 5 additions & 5 deletions types/vue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,18 @@ export type CreateElement = {
(tag: AsyncComponent<any, any, any, any>, data?: VNodeData, children?: VNodeChildren): VNode;
}

export interface Vue<Data = object, Methods = object, Computed = object, Props = object> {
$data: Data;
export interface Vue {
readonly $el: HTMLElement;
readonly $options: ComponentOptions<Data, Methods, Computed, Props>;
readonly $options: ComponentOptions<any, any, any, any>;
readonly $parent: Vue;
readonly $root: Vue;
readonly $children: Vue[];
readonly $refs: { [key: string]: Vue | Element | Vue[] | Element[] };
readonly $slots: { [key: string]: VNode[] };
readonly $scopedSlots: { [key: string]: ScopedSlot };
readonly $isServer: boolean;
readonly $props: Props;
readonly $data: Record<string, any>;
readonly $props: Record<string, any>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also make Vue generic so $data and $props can be typed. But I wonder if it is an overkill.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally made it generic but ran into problems.

Namely, VueConstructor has two construct signatures. Each of those signatures has two different sets of type parameters. They each constructed, at least in part, a Vue<Data, Methods, Computed, Props>`, but each gave different type arguments.

When extending a Vue<Data, Methods, Computed, Props>, TypeScript tries to find the right construct signature, but it can't because it's not really possible to make a meaningful set of type arguments for Vue` that would create the same output type for both signatures.

What it comes down to is that TypeScript has always had an assumption that the type parameters of a construct signature have had a direct correlation with the type parameters of the constructed type - but that's not entirely the case here. At least, that's my understanding of the problem.

So I could try to address this, but maybe down the line. Plus, does anyone need to access $data and $props outside of debugging?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed explanation!

Indeed, $data and $props are mainly for advanced usage like delegate / wrapper component (example). We would like to check template code in future. So a $props or $data might be helpful.

For ordinary users, Record should be enough.

readonly $ssrContext: any;

$mount(elementOrSelector?: Element | String, hydrating?: boolean): this;
Expand All @@ -70,7 +70,7 @@ export interface Vue<Data = object, Methods = object, Computed = object, Props =
$createElement: CreateElement;
}

export type CombinedVueInstance<Data, Methods, Computed, Props> = Data & Methods & Computed & Props & Vue<Data, Methods, Computed, Props>
export type CombinedVueInstance<Data, Methods, Computed, Props> = Data & Methods & Computed & Props & Vue;
export type ExtendedVue<Constructor extends VueConstructor, Data, Methods, Computed, Props> =
(new (...args: any[]) => CombinedVueInstance<Data, Methods, Computed, Props>) &
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As ExtendedVue is a sub-class of the Vue constructor, we can expect the constructor signature would only receive one argument like below?

new (options: any) => CombinedVueInstance<Data, Methods, Computed, Props>

Not sure whether we could annotate the options with ThisTypedComponentOptionsWithArrayProps etc. since the type declaration might be so complicated 😂

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As ExtendedVue is a sub-class of the Vue constructor, we can expect the constructor signature would only receive one argument like below?

@ktsn ExtendedVue creates an intersection with the mixin constructor (new (...args: any[]) => CombinedVueInstance<Data, Methods, Computed, Props>). This means it just absorbs the argument types of the Constructor type that's given. See microsoft/TypeScript#13743 for more details

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't understand about the mixin constructor correctly. Thank you for the explanation.

Constructor;
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy