1- import { Vue , CreateElement } from "./vue" ;
1+ import { Vue , CreateElement , CombinedVueInstance } from "./vue" ;
22import { VNode , VNodeData , VNodeDirective } from "./vnode" ;
33
44type Constructor = {
55new ( ...args :any [ ] ) :any ;
66}
77
8- export type Component = typeof Vue | ComponentOptions < Vue > | FunctionalComponentOptions ;
8+ // we don't support infer props in async component
9+ export type Component < Data = DefaultData < Vue > , Methods = DefaultMethods < Vue > , Computed = DefaultComputed , Props = DefaultProps > =
10+ | typeof Vue
11+ | FunctionalComponentOptions < Props >
12+ | ThisTypedComponentOptionsWithArrayProps < Vue , Data , Methods , Computed , keyof Props >
13+ | ThisTypedComponentOptionsWithRecordProps < Vue , Data , Methods , Computed , Props > ;
914
1015interface EsModuleComponent {
1116default :Component
1217}
1318
14- export type AsyncComponent = (
15- resolve :( component :Component ) => void ,
19+ export type AsyncComponent < Data = DefaultData < Vue > , Methods = DefaultMethods < Vue > , Computed = DefaultComputed , Props = DefaultProps > = (
20+ resolve :( component :Component < Data , Methods , Computed , Props > ) => void ,
1621reject :( reason ?:any ) => void
17- ) => Promise < Component | EsModuleComponent > | Component | void ;
22+ ) => Promise < Component | EsModuleComponent > | void ;
23+
24+ /**
25+ * When the `Computed` type parameter on `ComponentOptions` is inferred,
26+ * it should have a property with the return type of every get-accessor.
27+ * Since there isn't a way to query for the return type of a function, we allow TypeScript
28+ * to infer from the shape of `Accessors<Computed>` and work backwards.
29+ */
30+ export type Accessors < T > = {
31+ [ K in keyof T ] :( ( ) => T [ K ] ) | ComputedOptions < T [ K ] >
32+ }
1833
19- export interface ComponentOptions < V extends Vue > {
20- data ?:Object | ( ( this :V ) => Object ) ;
21- props ?:string [ ] | { [ key :string ] :PropOptions | Constructor | Constructor [ ] } ;
34+ /**
35+ * This type should be used when an array of strings is used for a component's `props` value.
36+ */
37+ export type ThisTypedComponentOptionsWithArrayProps < V extends Vue , Data , Methods , Computed , PropNames extends string > =
38+ object &
39+ ComponentOptions < V , Data | ( ( this :Readonly < Record < PropNames , any > > & V ) => Data ) , Methods , Computed , PropNames [ ] > &
40+ ThisType < CombinedVueInstance < V , Data , Methods , Computed , Readonly < Record < PropNames , any > > > > ;
41+
42+ /**
43+ * This type should be used when an object mapped to `PropOptions` is used for a component's `props` value.
44+ */
45+ export type ThisTypedComponentOptionsWithRecordProps < V extends Vue , Data , Methods , Computed , Props > =
46+ object &
47+ ComponentOptions < V , Data | ( ( this :Readonly < Props > & V ) => Data ) , Methods , Computed , RecordPropsDefinition < Props > > &
48+ ThisType < CombinedVueInstance < V , Data , Methods , Computed , Readonly < Props > > > ;
49+
50+ type DefaultData < V > = object | ( ( this :V ) => object ) ;
51+ type DefaultProps = Record < string , any > ;
52+ type DefaultMethods < V > = { [ key :string ] :( this :V , ...args :any [ ] ) => any } ;
53+ type DefaultComputed = { [ key :string ] :any } ;
54+ export interface ComponentOptions <
55+ V extends Vue ,
56+ Data = DefaultData < V > ,
57+ Methods = DefaultMethods < V > ,
58+ Computed = DefaultComputed ,
59+ PropsDef = PropsDefinition < DefaultProps > > {
60+ data ?:Data ;
61+ props ?:PropsDef ;
2262propsData ?:Object ;
23- computed ?:{ [ key : string ] : ( ( this : V ) => any ) | ComputedOptions < V > } ;
24- methods ?:{ [ key : string ] : ( this : V , ... args : any [ ] ) => any } ;
25- watch ?:{ [ key : string ] : ( { handler : WatchHandler < V , any > } & WatchOptions ) | WatchHandler < V , any > | string } ;
63+ computed ?:Accessors < Computed > ;
64+ methods ?:Methods ;
65+ watch ?:Record < string , WatchOptionsWithHandler < any > | WatchHandler < any > | string > ;
2666
2767el ?:Element | String ;
2868template ?:string ;
29- render ?( this : V , createElement :CreateElement ) :VNode ;
69+ render ?( createElement :CreateElement ) :VNode ;
3070renderError ?:( h :( ) => VNode , err :Error ) => VNode ;
3171staticRenderFns ?:( ( createElement :CreateElement ) => VNode ) [ ] ;
3272
3373beforeCreate ?( this :V ) :void ;
34- created ?( this : V ) :void ;
35- beforeDestroy ?( this : V ) :void ;
36- destroyed ?( this : V ) :void ;
37- beforeMount ?( this : V ) :void ;
38- mounted ?( this : V ) :void ;
39- beforeUpdate ?( this : V ) :void ;
40- updated ?( this : V ) :void ;
41- activated ?( this : V ) :void ;
42- deactivated ?( this : V ) :void ;
43-
44- directives ?:{ [ key :string ] :DirectiveOptions | DirectiveFunction } ;
45- components ?:{ [ key :string ] :Component | AsyncComponent } ;
74+ created ?( ) :void ;
75+ beforeDestroy ?( ) :void ;
76+ destroyed ?( ) :void ;
77+ beforeMount ?( ) :void ;
78+ mounted ?( ) :void ;
79+ beforeUpdate ?( ) :void ;
80+ updated ?( ) :void ;
81+ activated ?( ) :void ;
82+ deactivated ?( ) :void ;
83+
84+ directives ?:{ [ key :string ] :DirectiveFunction | DirectiveOptions } ;
85+ components ?:{ [ key :string ] :Component < any , any , any , any > | AsyncComponent < any , any , any , any > } ;
4686transitions ?:{ [ key :string ] :Object } ;
4787filters ?:{ [ key :string ] :Function } ;
4888
@@ -57,49 +97,64 @@ export interface ComponentOptions<V extends Vue> {
5797parent ?:Vue ;
5898mixins ?:( ComponentOptions < Vue > | typeof Vue ) [ ] ;
5999name ?:string ;
100+ // TODO: support properly inferred 'extends'
60101extends ?:ComponentOptions < Vue > | typeof Vue ;
61102delimiters ?:[ string , string ] ;
62103comments ?:boolean ;
63104inheritAttrs ?:boolean ;
64105}
65106
66- export interface FunctionalComponentOptions {
107+ export interface FunctionalComponentOptions < Props = DefaultProps , PropDefs = PropsDefinition < Props > > {
67108name ?:string ;
68- props ?:string [ ] | { [ key : string ] : PropOptions | Constructor | Constructor [ ] } ;
109+ props ?:PropDefs ;
69110inject ?:{ [ key :string ] :string | symbol } | string [ ] ;
70111functional :boolean ;
71- render ( this :never , createElement :CreateElement , context :RenderContext ) :VNode | void ;
112+ render ( this :undefined , createElement :CreateElement , context :RenderContext < Props > ) :VNode ;
72113}
73114
74- export interface RenderContext {
75- props :any ;
115+ export interface RenderContext < Props = DefaultProps > {
116+ props :Props ;
76117children :VNode [ ] ;
77118slots ( ) :any ;
78119data :VNodeData ;
79120parent :Vue ;
80121injections :any
81122}
82123
83- export interface PropOptions {
84- type ?:Constructor | Constructor [ ] | null ;
124+ export type Prop < T > = { ( ) :T } | { new ( ...args :any [ ] ) :T & object }
125+
126+ export type PropValidator < T > = PropOptions < T > | Prop < T > | Prop < T > [ ] ;
127+
128+ export interface PropOptions < T = any > {
129+ type ?:Prop < T > | Prop < T > [ ] ;
85130required ?:boolean ;
86- default ?:any ;
87- validator ?( value :any ) :boolean ;
131+ default ?:T | null | undefined | ( ( ) => object ) ;
132+ validator ?( value :T ) :boolean ;
88133}
89134
90- export interface ComputedOptions < V > {
91- get ?( this :V ) :any ;
92- set ?( this :V , value :any ) :void ;
135+ export type RecordPropsDefinition < T > = {
136+ [ K in keyof T ] :PropValidator < T [ K ] >
137+ }
138+ export type ArrayPropsDefinition < T > = ( keyof T ) [ ] ;
139+ export type PropsDefinition < T > = ArrayPropsDefinition < T > | RecordPropsDefinition < T > ;
140+
141+ export interface ComputedOptions < T > {
142+ get ?( ) :T ;
143+ set ?( value :T ) :void ;
93144cache ?:boolean ;
94145}
95146
96- export type WatchHandler < V , T > = ( this : V , val :T , oldVal :T ) => void ;
147+ export type WatchHandler < T > = ( val :T , oldVal :T ) => void ;
97148
98149export interface WatchOptions {
99150deep ?:boolean ;
100151immediate ?:boolean ;
101152}
102153
154+ export interface WatchOptionsWithHandler < T > extends WatchOptions {
155+ handler :WatchHandler < T > ;
156+ }
157+
103158export type DirectiveFunction = (
104159el :HTMLElement ,
105160binding :VNodeDirective ,