-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
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
Changes from 1 commit
5b5a88f
385a744
8cd5b9c
540a38f
f34f4f6
b1f40ce
355ff75
bc54007
e7ea5bb
ebde0b1
d78d14b
fc83771
a50c838
3c86b10
33a106c
0f586db
1092efe
ebd8c0b
c628103
e4a8545
3cac5c7
d55bc63
07eb21c
e7777d7
21d62a1
0958bda
6c76c45
5335788
8a1aab2
042e1c3
76de5dc
070460b
718dd7d
89f958b
da53a0a
e034641
c9f0939
754d0df
b784785
d5fbd81
37c5883
9e6931a
d9accb0
b90386a
67eab9c
97a401e
8df15b7
1ac0b7a
4649739
c953990
8901752
a7f84d9
5fa1ab9
a595239
00aa9d3
6091248
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,13 +44,13 @@ export type ThisTypedComponentOptionsWithRecordProps<V extends Vue, Data, Method | |
* A helper type that describes options for either functional or non-functional components. | ||
* Useful for `Vue.extend` and `Vue.component`. | ||
*/ | ||
export type FunctionalOrStandardComponentOptions<Data, Methods, Computed, PropNames extends string = never> = | ||
| FunctionalComponentOptions<PropNames[] | Record<PropNames, PropValidator>, Record<PropNames, any>> | ||
| ThisTypedComponentOptionsWithArrayProps<Vue, Data, Methods, Computed, PropNames> | ||
| ThisTypedComponentOptionsWithRecordProps<Vue, Data, Methods, Computed, Record<PropNames, PropOptions>>; | ||
export type FunctionalOrStandardComponentOptions<Data, Methods, Computed, Props> = | ||
| FunctionalComponentOptions<Props> | ||
| ThisTypedComponentOptionsWithArrayProps<Vue, Data, Methods, Computed, keyof Props> | ||
| ThisTypedComponentOptionsWithRecordProps<Vue, Data, Methods, Computed, Props>; | ||
|
||
type DefaultData<V> = object | ((this: V) => object); | ||
type DefaultProp = string[] | { [key: string]: PropOptions | Constructor | Constructor[] }; | ||
type DefaultProp = Record<string, any>; | ||
type DefaultMethods<V> = { [key: string]: (this: V, ...args: any[]) => any }; | ||
type DefaultComputed = { [key: string]: any }; | ||
export interface ComponentOptions< | ||
|
@@ -60,7 +60,7 @@ export interface ComponentOptions< | |
Computed=DefaultComputed, | ||
Props=DefaultProp> { | ||
data?: Data; | ||
props?: Props; | ||
props?: (keyof Props)[] | PropsDefinition<Props>; | ||
propsData?: Object; | ||
computed?: Accessors<Computed>; | ||
methods?: Methods; | ||
|
@@ -97,7 +97,7 @@ export interface ComponentOptions< | |
}; | ||
|
||
parent?: Vue; | ||
mixins?: (ComponentOptions<any, any, any, any> | typeof Vue)[]; | ||
mixins?: (ComponentOptions<Vue> | typeof Vue)[]; | ||
name?: string; | ||
// TODO: support properly inferred 'extends' | ||
extends?: ComponentOptions<any, any, any, any> | typeof Vue; | ||
|
@@ -106,11 +106,11 @@ export interface ComponentOptions< | |
inheritAttrs?: boolean; | ||
} | ||
|
||
export interface FunctionalComponentOptions<Props = object, ContextProps = object> { | ||
export interface FunctionalComponentOptions<Props> { | ||
name?: string; | ||
props?: Props; | ||
props?: keyof Props | PropsDefinition<Props>; | ||
functional: boolean; | ||
render(this: undefined, createElement: CreateElement, context: RenderContext<ContextProps>): VNode; | ||
render(this: undefined, createElement: CreateElement, context: RenderContext<Props>): VNode; | ||
} | ||
|
||
export interface RenderContext<Props> { | ||
|
@@ -122,15 +122,33 @@ export interface RenderContext<Props> { | |
injections: any | ||
} | ||
|
||
export type PropValidator = PropOptions | Constructor | Constructor[]; | ||
declare global { | ||
interface StringConstructor { | ||
'@@vueProp': string; | ||
} | ||
interface BooleanConstructor { | ||
'@@vueProp': boolean; | ||
} | ||
interface NumberConstructor { | ||
'@@vueProp': number; | ||
} | ||
} | ||
|
||
export type Prop<T> = { '@@vueProp': T } | { new (...args: any[]): T } | ||
|
||
export type PropValidator<T> = PropOptions<T> | Prop<T> | Prop<T>[]; | ||
|
||
export interface PropOptions { | ||
type?: Constructor | Constructor[] | null; | ||
export interface PropOptions<T> { | ||
type?: Prop<T> | Prop<T>[]; | ||
required?: boolean; | ||
default?: string | number | boolean | null | undefined | (() => object); | ||
default?: T | null | undefined | (() => object); | ||
validator?(value: any): boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we let There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The point of validator is testing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But at least its type is specified by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, I forget there is builtin check before validator! |
||
} | ||
|
||
export type PropsDefinition<T> = { | ||
[K in keyof T]: PropValidator<T[K]> | ||
} | ||
|
||
export interface ComputedOptions<T> { | ||
get?(): T; | ||
set?(value: T): void; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,13 +77,10 @@ export type CombinedVueInstance<Instance extends Vue, Data, Methods, Computed, P | |
export type ExtendedVue<Instance extends Vue, Data, Methods, Computed, Props> = VueConstructor<CombinedVueInstance<Instance, Data, Methods, Computed, Props> & Vue>; | ||
|
||
export interface VueConstructor<V extends Vue = Vue> { | ||
new <Data = object, Methods = object, Computed = object, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): CombinedVueInstance<V, Data, Methods, Computed, Record<PropNames, any>>; | ||
new <Data = object, Methods = object, Computed = object, Props extends Record<string, PropValidator> = {}>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): CombinedVueInstance<V, Data, Methods, Computed, Record<keyof Props, any>>; | ||
new <Data = object, Methods = object, Computed = object, Props = object>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): CombinedVueInstance<V, Data, Methods, Computed, Props>; | ||
|
||
extend<PropNames extends string = never>(definition: FunctionalComponentOptions<PropNames[], Record<PropNames, any>>): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>>; | ||
extend<Props extends Record<string, PropValidator>>(definition: FunctionalComponentOptions<Props, Record<keyof Props, any>>): ExtendedVue<V, {}, {}, {}, Record<keyof Props, any>>; | ||
extend<Data, Methods, Computed, PropNames extends string = never>(options: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, any>>; | ||
extend<Data, Methods, Computed, Props extends Record<string, PropValidator>>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Record<keyof Props, any>>; | ||
extend<Props>(definition: FunctionalComponentOptions<Props>): ExtendedVue<V, {}, {}, {}, Props>; | ||
extend<Data, Methods, Computed, Props>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having tried this out, while Maybe we should reorder this so that 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately we haven't yet implemented that. This isn't a blocker though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm merging this in preparation for 2.5 release. We can improve upon this in a separate PR later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
|
||
nextTick(callback: () => void, context?: any[]): void; | ||
nextTick(): Promise<void> | ||
|
@@ -100,11 +97,8 @@ export interface VueConstructor<V extends Vue = Vue> { | |
|
||
component(id: string): VueConstructor; | ||
component<VC extends VueConstructor>(id: string, constructor: VC): VC; | ||
component<Data, Methods, Computed, PropNames extends string = never>(id: string, definition: AsyncComponent<Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, any>>; | ||
component<PropNames extends string = never>(id: string, definition: FunctionalComponentOptions<PropNames[], Record<PropNames, any>>): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>>; | ||
component<Props extends Record<string, PropValidator>>(id: string, definition: FunctionalComponentOptions<Props, Record<keyof Props, any>>): ExtendedVue<V, {}, {}, {}, Record<keyof Props, any>>; | ||
component<Data, Methods, Computed, PropNames extends string = never>(id: string, definition: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, any>>; | ||
component<Data, Methods, Computed, Props extends Record<string, PropValidator>>(id: string, definition?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Record<keyof Props, any>>; | ||
component<Props>(id: string, definition: FunctionalComponentOptions<Props>): ExtendedVue<V, {}, {}, {}, Props>; | ||
component<Data, Methods, Computed, Props>(id: string, definition?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Record<keyof Props, any>>; | ||
|
||
use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): void; | ||
mixin(mixin: typeof Vue | ComponentOptions<any, any, any, any>): void; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is clever declaration :D