types: types for setup() + format types

This commit is contained in:
Evan You 2022-05-27 17:26:55 +08:00
parent f29ad1def5
commit 93214586aa
15 changed files with 1089 additions and 676 deletions

22
types/index.d.ts vendored
View File

@ -1,12 +1,9 @@
import { Vue } from "./vue";
import "./umd";
import { Vue } from './vue'
import './umd'
export default Vue;
export default Vue
export {
CreateElement,
VueConstructor
} from "./vue";
export { CreateElement, VueConstructor } from './vue'
export {
Component,
@ -22,12 +19,9 @@ export {
WatchOptionsWithHandler,
DirectiveFunction,
DirectiveOptions
} from "./options";
} from './options'
export {
PluginFunction,
PluginObject
} from "./plugin";
export { PluginFunction, PluginObject } from './plugin'
export {
VNodeChildren,
@ -36,4 +30,6 @@ export {
VNodeComponentOptions,
VNodeData,
VNodeDirective
} from "./vnode";
} from './vnode'
export { h, getCurrentInstance } from './v3'

349
types/options.d.ts vendored
View File

@ -1,37 +1,73 @@
import { Vue, CreateElement, CombinedVueInstance } from "./vue";
import { VNode, VNodeData, VNodeDirective, NormalizedScopedSlot } from "./vnode";
import { Vue, CreateElement, CombinedVueInstance } from './vue'
import { VNode, VNodeData, VNodeDirective, NormalizedScopedSlot } from './vnode'
import { SetupContext } from './v3'
type Constructor = {
new (...args: any[]): any;
new (...args: any[]): any
}
// we don't support infer props in async component
// N.B. ComponentOptions<V> is contravariant, the default generic should be bottom type
export type Component<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> =
export type Component<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps,
SetupBindings = {}
> =
| typeof Vue
| FunctionalComponentOptions<Props>
| ComponentOptions<never, Data, Methods, Computed, Props>
| ComponentOptions<never, Data, Methods, Computed, Props, SetupBindings>
type EsModule<T> = T | { default: T }
type ImportedComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps>
= EsModule<Component<Data, Methods, Computed, Props>>
type ImportedComponent<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps,
SetupBindings = {}
> = EsModule<Component<Data, Methods, Computed, Props, SetupBindings>>
export type AsyncComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps>
= AsyncComponentPromise<Data, Methods, Computed, Props>
| AsyncComponentFactory<Data, Methods, Computed, Props>
export type AsyncComponent<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps,
SetupBindings = {}
> =
| AsyncComponentPromise<Data, Methods, Computed, Props, SetupBindings>
| AsyncComponentFactory<Data, Methods, Computed, Props, SetupBindings>
export type AsyncComponentPromise<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = (
resolve: (component: Component<Data, Methods, Computed, Props>) => void,
export type AsyncComponentPromise<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps,
SetupBindings = {}
> = (
resolve: (
component: Component<Data, Methods, Computed, Props, SetupBindings>
) => void,
reject: (reason?: any) => void
) => Promise<ImportedComponent<Data, Methods, Computed, Props>> | void;
) => Promise<
ImportedComponent<Data, Methods, Computed, Props, SetupBindings>
> | void
export type AsyncComponentFactory<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = () => {
component: Promise<ImportedComponent<Data, Methods, Computed, Props>>;
loading?: ImportedComponent;
error?: ImportedComponent;
delay?: number;
timeout?: number;
export type AsyncComponentFactory<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps,
SetupBindings = {}
> = () => {
component: Promise<
ImportedComponent<Data, Methods, Computed, Props, SetupBindings>
>
loading?: ImportedComponent
error?: ImportedComponent
delay?: number
timeout?: number
}
/**
@ -48,141 +84,212 @@ type DataDef<Data, Props, V> = Data | ((this: Readonly<Props> & V) => Data)
/**
* This type should be used when an array of strings is used for a component's `props` value.
*/
export type ThisTypedComponentOptionsWithArrayProps<V extends Vue, Data, Methods, Computed, PropNames extends string> =
object &
ComponentOptions<V, DataDef<Data, Record<PropNames, any>, V>, Methods, Computed, PropNames[], Record<PropNames, any>> &
ThisType<CombinedVueInstance<V, Data, Methods, Computed, Readonly<Record<PropNames, any>>>>;
export type ThisTypedComponentOptionsWithArrayProps<
V extends Vue,
Data,
Methods,
Computed,
PropNames extends string,
SetupBindings
> = object &
ComponentOptions<
V,
DataDef<Data, Record<PropNames, any>, V>,
Methods,
Computed,
PropNames[],
Record<PropNames, any>,
SetupBindings
> &
ThisType<
CombinedVueInstance<
V,
Data,
Methods,
Computed,
Readonly<Record<PropNames, any>>,
SetupBindings
>
>
/**
* This type should be used when an object mapped to `PropOptions` is used for a component's `props` value.
*/
export type ThisTypedComponentOptionsWithRecordProps<V extends Vue, Data, Methods, Computed, Props> =
object &
ComponentOptions<V, DataDef<Data, Props, V>, Methods, Computed, RecordPropsDefinition<Props>, Props> &
ThisType<CombinedVueInstance<V, Data, Methods, Computed, Readonly<Props>>>;
export type ThisTypedComponentOptionsWithRecordProps<
V extends Vue,
Data,
Methods,
Computed,
Props,
SetupBindings
> = object &
ComponentOptions<
V,
DataDef<Data, Props, V>,
Methods,
Computed,
RecordPropsDefinition<Props>,
Props,
SetupBindings
> &
ThisType<
CombinedVueInstance<
V,
Data,
Methods,
Computed,
Readonly<Props>,
SetupBindings
>
>
type DefaultData<V> = object | ((this: V) => object)
type DefaultProps = Record<string, any>
type DefaultMethods<V> = { [key: string]: (this: V, ...args: any[]) => any }
type DefaultComputed = { [key: string]: any }
type DefaultData<V> = object | ((this: V) => object);
type DefaultProps = Record<string, any>;
type DefaultMethods<V> = { [key: string]: (this: V, ...args: any[]) => any };
type DefaultComputed = { [key: string]: any };
export interface ComponentOptions<
V extends Vue,
Data=DefaultData<V>,
Methods=DefaultMethods<V>,
Computed=DefaultComputed,
PropsDef=PropsDefinition<DefaultProps>,
Props=DefaultProps> {
data?: Data;
props?: PropsDef;
propsData?: object;
computed?: Accessors<Computed>;
methods?: Methods;
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any>>;
Data = DefaultData<V>,
Methods = DefaultMethods<V>,
Computed = DefaultComputed,
PropsDef = PropsDefinition<DefaultProps>,
Props = DefaultProps,
RawBindings = {}
> {
data?: Data
props?: PropsDef
propsData?: object
computed?: Accessors<Computed>
methods?: Methods
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any>>
el?: Element | string;
template?: string;
setup?: (
this: void,
props: Props,
ctx: SetupContext
) => Promise<RawBindings> | RawBindings | ((h: CreateElement) => VNode) | void
el?: Element | string
template?: string
// hack is for functional component type inference, should not be used in user code
render?(createElement: CreateElement, hack: RenderContext<Props>): VNode;
renderError?(createElement: CreateElement, err: Error): VNode;
staticRenderFns?: ((createElement: CreateElement) => VNode)[];
render?(createElement: CreateElement, hack: RenderContext<Props>): VNode
renderError?(createElement: CreateElement, err: Error): VNode
staticRenderFns?: ((createElement: CreateElement) => VNode)[]
beforeCreate?(this: V): void;
created?(): void;
beforeDestroy?(): void;
destroyed?(): void;
beforeMount?(): void;
mounted?(): void;
beforeUpdate?(): void;
updated?(): void;
activated?(): void;
deactivated?(): void;
errorCaptured?(err: Error, vm: Vue, info: string): boolean | void;
serverPrefetch?(this: V): Promise<void>;
beforeCreate?(this: V): void
created?(): void
beforeDestroy?(): void
destroyed?(): void
beforeMount?(): void
mounted?(): void
beforeUpdate?(): void
updated?(): void
activated?(): void
deactivated?(): void
errorCaptured?(err: Error, vm: Vue, info: string): boolean | void
serverPrefetch?(this: V): Promise<void>
directives?: { [key: string]: DirectiveFunction | DirectiveOptions };
components?: { [key: string]: Component<any, any, any, any> | AsyncComponent<any, any, any, any> };
transitions?: { [key: string]: object };
filters?: { [key: string]: Function };
directives?: { [key: string]: DirectiveFunction | DirectiveOptions }
components?: {
[key: string]:
| Component<any, any, any, any>
| AsyncComponent<any, any, any, any>
}
transitions?: { [key: string]: object }
filters?: { [key: string]: Function }
provide?: object | (() => object);
inject?: InjectOptions;
provide?: object | (() => object)
inject?: InjectOptions
model?: {
prop?: string;
event?: string;
};
prop?: string
event?: string
}
parent?: Vue;
mixins?: (ComponentOptions<Vue> | typeof Vue)[];
name?: string;
parent?: Vue
mixins?: (ComponentOptions<Vue> | typeof Vue)[]
name?: string
// TODO: support properly inferred 'extends'
extends?: ComponentOptions<Vue> | typeof Vue;
delimiters?: [string, string];
comments?: boolean;
inheritAttrs?: boolean;
extends?: ComponentOptions<Vue> | typeof Vue
delimiters?: [string, string]
comments?: boolean
inheritAttrs?: boolean
}
export interface FunctionalComponentOptions<Props = DefaultProps, PropDefs = PropsDefinition<Props>> {
name?: string;
props?: PropDefs;
export interface FunctionalComponentOptions<
Props = DefaultProps,
PropDefs = PropsDefinition<Props>
> {
name?: string
props?: PropDefs
model?: {
prop?: string;
event?: string;
};
inject?: InjectOptions;
functional: boolean;
render?(this: undefined, createElement: CreateElement, context: RenderContext<Props>): VNode | VNode[];
prop?: string
event?: string
}
inject?: InjectOptions
functional: boolean
render?(
this: undefined,
createElement: CreateElement,
context: RenderContext<Props>
): VNode | VNode[]
}
export interface RenderContext<Props=DefaultProps> {
props: Props;
children: VNode[];
slots(): any;
data: VNodeData;
parent: Vue;
listeners: { [key: string]: Function | Function[] };
scopedSlots: { [key: string]: NormalizedScopedSlot };
export interface RenderContext<Props = DefaultProps> {
props: Props
children: VNode[]
slots(): any
data: VNodeData
parent: Vue
listeners: { [key: string]: Function | Function[] }
scopedSlots: { [key: string]: NormalizedScopedSlot }
injections: any
}
export type Prop<T> = { (): T } | { new(...args: never[]): T & object } | { new(...args: string[]): Function }
export type Prop<T> =
| { (): T }
| { new (...args: never[]): T & object }
| { new (...args: string[]): Function }
export type PropType<T> = Prop<T> | Prop<T>[];
export type PropType<T> = Prop<T> | Prop<T>[]
export type PropValidator<T> = PropOptions<T> | PropType<T>;
export type PropValidator<T> = PropOptions<T> | PropType<T>
export interface PropOptions<T=any> {
type?: PropType<T>;
required?: boolean;
default?: T | null | undefined | (() => T | null | undefined);
validator?(value: T): boolean;
export interface PropOptions<T = any> {
type?: PropType<T>
required?: boolean
default?: T | null | undefined | (() => T | null | undefined)
validator?(value: T): boolean
}
export type RecordPropsDefinition<T> = {
[K in keyof T]: PropValidator<T[K]>
}
export type ArrayPropsDefinition<T> = (keyof T)[];
export type PropsDefinition<T> = ArrayPropsDefinition<T> | RecordPropsDefinition<T>;
export type ArrayPropsDefinition<T> = (keyof T)[]
export type PropsDefinition<T> =
| ArrayPropsDefinition<T>
| RecordPropsDefinition<T>
export interface ComputedOptions<T> {
get?(): T;
set?(value: T): void;
cache?: boolean;
get?(): T
set?(value: T): void
cache?: boolean
}
export type WatchHandler<T> = string | ((val: T, oldVal: T) => void);
export type WatchHandler<T> = string | ((val: T, oldVal: T) => void)
export interface WatchOptions {
deep?: boolean;
immediate?: boolean;
deep?: boolean
immediate?: boolean
}
export interface WatchOptionsWithHandler<T> extends WatchOptions {
handler: WatchHandler<T>;
handler: WatchHandler<T>
}
export interface DirectiveBinding extends Readonly<VNodeDirective> {
readonly modifiers: { [key: string]: boolean };
readonly modifiers: { [key: string]: boolean }
}
export type DirectiveFunction = (
@ -190,18 +297,20 @@ export type DirectiveFunction = (
binding: DirectiveBinding,
vnode: VNode,
oldVnode: VNode
) => void;
) => void
export interface DirectiveOptions {
bind?: DirectiveFunction;
inserted?: DirectiveFunction;
update?: DirectiveFunction;
componentUpdated?: DirectiveFunction;
unbind?: DirectiveFunction;
bind?: DirectiveFunction
inserted?: DirectiveFunction
update?: DirectiveFunction
componentUpdated?: DirectiveFunction
unbind?: DirectiveFunction
}
export type InjectKey = string | symbol;
export type InjectKey = string | symbol
export type InjectOptions = {
[key: string]: InjectKey | { from?: InjectKey, default?: any }
} | string[];
export type InjectOptions =
| {
[key: string]: InjectKey | { from?: InjectKey; default?: any }
}
| string[]

8
types/plugin.d.ts vendored
View File

@ -1,8 +1,8 @@
import { Vue as _Vue } from "./vue";
import { Vue as _Vue } from './vue'
export type PluginFunction<T> = (Vue: typeof _Vue, options?: T) => void;
export type PluginFunction<T> = (Vue: typeof _Vue, options?: T) => void
export interface PluginObject<T> {
install: PluginFunction<T>;
[key: string]: any;
install: PluginFunction<T>
[key: string]: any
}

View File

@ -1,8 +1,8 @@
import Vue, { AsyncComponent, Component } from "../index";
import Vue, { AsyncComponent, Component } from '../index'
const a: AsyncComponent = () => ({
component: new Promise<Component>((res, rej) => {
res({ template: "" })
res({ template: '' })
})
})
@ -10,14 +10,14 @@ const b: AsyncComponent = () => ({
// @ts-expect-error component has to be a Promise that resolves to a component
component: () =>
new Promise<Component>((res, rej) => {
res({ template: "" })
res({ template: '' })
})
})
const c: AsyncComponent = () =>
new Promise<Component>((res, rej) => {
res({
template: ""
template: ''
})
})
@ -25,7 +25,7 @@ const d: AsyncComponent = () =>
new Promise<{ default: Component }>((res, rej) => {
res({
default: {
template: ""
template: ''
}
})
})
@ -34,11 +34,11 @@ const e: AsyncComponent = () => ({
component: new Promise<{ default: Component }>((res, rej) => {
res({
default: {
template: ""
template: ''
}
})
})
})
// Test that Vue.component accepts any AsyncComponent
Vue.component("async-compponent1", a)
Vue.component('async-compponent1', a)

View File

@ -1,46 +1,46 @@
import Vue from "../index";
import Vue from '../index'
declare module "../vue" {
declare module '../vue' {
// add instance property and method
interface Vue {
$instanceProperty: string;
$instanceMethod(): void;
$instanceProperty: string
$instanceMethod(): void
}
// add static property and method
interface VueConstructor {
staticProperty: string;
staticMethod(): void;
staticProperty: string
staticMethod(): void
}
}
// augment ComponentOptions
declare module "../options" {
declare module '../options' {
interface ComponentOptions<V extends Vue> {
foo?: string;
foo?: string
}
}
const vm = new Vue({
props: ["bar"],
props: ['bar'],
data: {
a: true
},
foo: "foo",
foo: 'foo',
methods: {
foo() {
this.a = false;
this.a = false
}
},
computed: {
BAR(): string {
return this.bar.toUpperCase();
return this.bar.toUpperCase()
}
}
});
})
vm.$instanceProperty;
vm.$instanceMethod();
vm.$instanceProperty
vm.$instanceMethod()
Vue.staticProperty;
Vue.staticMethod();
Vue.staticProperty
Vue.staticMethod()

View File

@ -1,9 +1,9 @@
import Vue, { PropType, VNode } from "../index";
import { ComponentOptions, Component } from "../index";
import { CreateElement } from "../vue";
import Vue, { PropType, VNode } from '../index'
import { ComponentOptions, Component } from '../index'
import { CreateElement } from '../vue'
interface MyComponent extends Vue {
a: number;
a: number
}
const option: ComponentOptions<MyComponent> = {
@ -20,10 +20,10 @@ const componentType: Component = option
Vue.component('sub-component', {
components: {
a: Vue.component(""),
a: Vue.component(''),
b: {}
}
});
})
Vue.component('prop-component', {
props: {
@ -31,7 +31,7 @@ Vue.component('prop-component', {
name: {
type: String,
default: '0',
required: true,
required: true
}
},
data() {
@ -40,7 +40,7 @@ Vue.component('prop-component', {
capName: this.name.toUpperCase()
}
}
});
})
Vue.component('string-prop', {
props: ['size', 'name'],
@ -50,7 +50,7 @@ Vue.component('string-prop', {
capName: this.name.isany
}
}
});
})
class User {
private u = 1
@ -60,15 +60,15 @@ class Cat {
}
interface IUser {
foo: string,
foo: string
bar: number
}
interface ICat {
foo: any,
foo: any
bar: object
}
type ConfirmCallback = (confirm: boolean) => void;
type ConfirmCallback = (confirm: boolean) => void
Vue.component('union-prop', {
props: {
@ -79,16 +79,16 @@ Vue.component('union-prop', {
union: [User, Number] as PropType<User | number>
},
data() {
this.cat;
this.complexUnion;
this.kittyUser;
this.callback(true);
this.union;
this.cat
this.complexUnion
this.kittyUser
this.callback(true)
this.union
return {
fixedSize: this.union,
fixedSize: this.union
}
}
});
})
Vue.component('union-prop-with-no-casting', {
props: {
@ -98,10 +98,10 @@ Vue.component('union-prop-with-no-casting', {
regex: RegExp
},
data() {
this.mixed;
this.object;
this.primitive;
this.regex.compile;
this.mixed
this.object
this.primitive
this.regex.compile
}
})
@ -113,9 +113,9 @@ Vue.component('prop-with-primitive-default', {
}
},
created(): void {
this.id;
this.id
}
});
})
Vue.component('component', {
data() {
@ -130,40 +130,40 @@ Vue.component('component', {
name: {
type: String,
default: '0',
required: true,
required: true
}
},
propsData: {
msg: "Hello"
msg: 'Hello'
},
computed: {
aDouble(): number {
return this.a * 2;
return this.a * 2
},
aPlus: {
get(): number {
return this.a + 1;
return this.a + 1
},
set(v: number) {
this.a = v - 1;
this.a = v - 1
},
cache: false
}
},
methods: {
plus(): void {
this.a++;
this.aDouble.toFixed();
this.aPlus = 1;
this.size.toFixed();
this.a++
this.aDouble.toFixed()
this.aPlus = 1
this.size.toFixed()
}
},
watch: {
'a': function(val: number, oldVal: number) {
console.log(`new: ${val}, old: ${oldVal}`);
a: function (val: number, oldVal: number) {
console.log(`new: ${val}, old: ${oldVal}`)
},
'b': 'someMethod',
'c': {
b: 'someMethod',
c: {
handler(val, oldVal) {
this.a = val
},
@ -174,71 +174,77 @@ Vue.component('component', {
immediate: true
}
},
el: "#app",
template: "<div>{{ message }}</div>",
el: '#app',
template: '<div>{{ message }}</div>',
render(createElement) {
return createElement("div", {
attrs: {
id: "foo"
return createElement(
'div',
{
attrs: {
id: 'foo'
},
props: {
myProp: 'bar'
},
directives: [
{
name: 'a',
value: 'foo'
}
],
domProps: {
innerHTML: 'baz'
},
on: {
click: new Function()
},
nativeOn: {
click: new Function()
},
class: {
foo: true,
bar: false
},
style: {
color: 'red',
fontSize: '14px'
},
key: 'myKey',
ref: 'myRef',
refInFor: true
},
props: {
myProp: "bar"
},
directives: [{
name: 'a',
value: 'foo'
}],
domProps: {
innerHTML: "baz"
},
on: {
click: new Function
},
nativeOn: {
click: new Function
},
class: {
foo: true,
bar: false
},
style: {
color: 'red',
fontSize: '14px'
},
key: 'myKey',
ref: 'myRef',
refInFor: true
}, [
createElement(),
createElement("div", "message"),
createElement(Vue.component("component")),
createElement({} as ComponentOptions<Vue>),
createElement({
functional: true,
render(c: CreateElement) {
return createElement()
}
}),
[
createElement(),
createElement('div', 'message'),
createElement(Vue.component('component')),
createElement({} as ComponentOptions<Vue>),
createElement({
functional: true,
render(c: CreateElement) {
return createElement()
}
}),
createElement(() => Vue.component("component")),
createElement(() => ( {} as ComponentOptions<Vue> )),
createElement((resolve, reject) => {
resolve({} as ComponentOptions<Vue>);
reject();
}),
createElement(() => Vue.component('component')),
createElement(() => ({} as ComponentOptions<Vue>)),
createElement((resolve, reject) => {
resolve({} as ComponentOptions<Vue>)
reject()
}),
"message",
'message',
[createElement("div", "message")]
]);
[createElement('div', 'message')]
]
)
},
renderError(createElement, err) {
return createElement('pre', { style: { color: 'red' }}, err.stack)
return createElement('pre', { style: { color: 'red' } }, err.stack)
},
staticRenderFns: [],
beforeCreate() {
(this as any).a = 1;
;(this as any).a = 1
},
created() {},
beforeDestroy() {},
@ -255,7 +261,7 @@ Vue.component('component', {
info.toUpperCase()
return true
},
serverPrefetch () {
serverPrefetch() {
return Promise.resolve()
},
@ -268,44 +274,43 @@ Vue.component('component', {
unbind() {}
},
b(el, binding, vnode, oldVnode) {
el.textContent;
el.textContent
binding.name;
binding.value;
binding.oldValue;
binding.expression;
binding.arg;
binding.modifiers["modifier"];
binding.name
binding.value
binding.oldValue
binding.expression
binding.arg
binding.modifiers['modifier']
}
},
components: {
a: Vue.component(""),
a: Vue.component(''),
b: {} as ComponentOptions<Vue>
},
transitions: {},
filters: {
double(value: number) {
return value * 2;
return value * 2
}
},
parent: new Vue,
mixins: [Vue.component(""), ({} as ComponentOptions<Vue>)],
name: "Component",
parent: new Vue(),
mixins: [Vue.component(''), {} as ComponentOptions<Vue>],
name: 'Component',
extends: {} as ComponentOptions<Vue>,
delimiters: ["${", "}"]
});
delimiters: ['${', '}']
})
Vue.component('custom-prop-type-function', {
props: {
callback: Function as PropType<(confirm: boolean) => void>,
callback: Function as PropType<(confirm: boolean) => void>
},
methods: {
confirm(){
this.callback(true);
confirm() {
this.callback(true)
}
}
});
})
Vue.component('provide-inject', {
provide: {
@ -316,7 +321,7 @@ Vue.component('provide-inject', {
injectBar: Symbol(),
injectBaz: { from: 'baz' },
injectQux: { default: 1 },
injectQuux: { from: 'quuz', default: () => ({ value: 1 })}
injectQuux: { from: 'quuz', default: () => ({ value: 1 }) }
}
})
@ -327,13 +332,13 @@ Vue.component('provide-function', {
})
Vue.component('component-with-slot', {
render (h): VNode {
render(h): VNode {
return h('div', this.$slots.default)
}
})
Vue.component('component-with-scoped-slot', {
render (h) {
render(h) {
interface ScopedSlotProps {
msg: string
}
@ -367,11 +372,12 @@ Vue.component('component-with-scoped-slot', {
},
components: {
child: {
render (this: Vue, h: CreateElement) {
render(this: Vue, h: CreateElement) {
const defaultSlot = this.$scopedSlots['default']!({ msg: 'hi' })
defaultSlot && defaultSlot.forEach(vnode => {
vnode.tag
})
defaultSlot &&
defaultSlot.forEach(vnode => {
vnode.tag
})
return h('div', [
defaultSlot,
this.$scopedSlots['item']!({ msg: 'hello' })
@ -382,7 +388,7 @@ Vue.component('component-with-scoped-slot', {
})
Vue.component('narrow-array-of-vnode-type', {
render (h): VNode {
render(h): VNode {
const slot = this.$scopedSlots.default!({})
if (typeof slot === 'string') {
// <template slot-scope="data">bare string</template>
@ -410,16 +416,16 @@ Vue.component('functional-component', {
functional: true,
inject: ['foo'],
render(createElement, context) {
context.props;
context.children;
context.slots();
context.data;
context.parent;
context.scopedSlots;
context.listeners.click;
return createElement("div", {}, context.children);
context.props
context.children
context.slots()
context.data
context.parent
context.scopedSlots
context.listeners.click
return createElement('div', {}, context.children)
}
});
})
Vue.component('functional-component-object-inject', {
functional: true,
@ -428,7 +434,7 @@ Vue.component('functional-component-object-inject', {
bar: Symbol(),
baz: { from: 'baz' },
qux: { default: 1 },
quux: { from: 'quuz', default: () => ({ value: 1 })}
quux: { from: 'quuz', default: () => ({ value: 1 }) }
},
render(h) {
return h('div')
@ -443,23 +449,25 @@ Vue.component('functional-component-multi-root', {
functional: true,
render(h) {
return [
h("tr", [h("td", "foo"), h("td", "bar")]),
h("tr", [h("td", "lorem"), h("td", "ipsum")])
h('tr', [h('td', 'foo'), h('td', 'bar')]),
h('tr', [h('td', 'lorem'), h('td', 'ipsum')])
]
}
})
Vue.component("async-component", ((resolve, reject) => {
Vue.component('async-component', (resolve, reject) => {
setTimeout(() => {
resolve(Vue.component("component"));
}, 0);
return new Promise((resolve) => {
resolve(Vue.component('component'))
}, 0)
return new Promise(resolve => {
resolve({
functional: true,
render(h: CreateElement) { return h('div') }
});
render(h: CreateElement) {
return h('div')
}
})
})
}));
})
Vue.component('functional-component-v-model', {
props: ['foo'],
@ -469,33 +477,33 @@ Vue.component('functional-component-v-model', {
event: 'change'
},
render(createElement, context) {
return createElement("input", {
return createElement('input', {
on: {
input: new Function()
},
domProps: {
value: context.props.foo
}
});
})
}
});
})
Vue.component('async-es-module-component', () => import('./es-module'))
Vue.component('directive-expression-optional-string', {
render(createElement) {
return createElement("div", {
return createElement('div', {
directives: [
{
name: 'has-expression',
value: 2,
expression: '1 + 1',
}, {
name: 'no-expression',
value: 'foo',
expression: '1 + 1'
},
],
{
name: 'no-expression',
value: 'foo'
}
]
})
}
});
})

View File

@ -1,20 +1,20 @@
import Vue from "../index";
import { PluginFunction, PluginObject } from "../index";
import Vue from '../index'
import { PluginFunction, PluginObject } from '../index'
class Option {
prefix: string = "";
suffix: string = "";
prefix: string = ''
suffix: string = ''
}
const plugin: PluginObject<Option> = {
install(Vue, option) {
if (typeof option !== "undefined") {
const {prefix, suffix} = option;
if (typeof option !== 'undefined') {
const { prefix, suffix } = option
}
}
}
const installer: PluginFunction<Option> = function(Vue, option) { }
const installer: PluginFunction<Option> = function (Vue, option) {}
Vue.use(plugin, new Option);
Vue.use(installer, new Option);
Vue.use(installer, new Option, new Option, new Option);
Vue.use(plugin, new Option())
Vue.use(installer, new Option())
Vue.use(installer, new Option(), new Option(), new Option())

35
types/test/setup-test.ts Normal file
View File

@ -0,0 +1,35 @@
import Vue from '../index'
// object props
Vue.extend({
props: {
foo: String,
bar: Number
},
setup(props) {
props.foo + 'foo'
props.bar + 123
}
})
// array props
Vue.extend({
props: ['foo', 'bar'],
setup(props) {
props.foo
props.bar
}
})
// context
Vue.extend({
setup(_props, ctx) {
if (ctx.attrs.id) {
}
ctx.emit('foo')
ctx.slots.default && ctx.slots.default()
ctx.expose({
foo: 123
})
}
})

View File

@ -1,119 +1,127 @@
import Vue, { VNode, VNodeDirective } from '../index';
import VueSSRClientPlugin = require('../../packages/vue-server-renderer/client-plugin');
import VueSSRServerPlugin = require('../../packages/vue-server-renderer/server-plugin');
import webpack = require('webpack');
import { readFileSync } from 'fs';
import { createRenderer, createBundleRenderer } from '../../packages/vue-server-renderer';
import Vue, { VNode, VNodeDirective } from '../index'
import VueSSRClientPlugin = require('../../packages/vue-server-renderer/client-plugin')
import VueSSRServerPlugin = require('../../packages/vue-server-renderer/server-plugin')
import webpack = require('webpack')
import { readFileSync } from 'fs'
import {
createRenderer,
createBundleRenderer
} from '../../packages/vue-server-renderer'
function createApp (context: any) {
function createApp(context: any) {
return new Vue({
data: {
url: context.url
},
template: `<div>The visited URL is: {{ url }}</div>`
});
})
}
// Renderer test
const app = createApp({ url: 'http://localhost:8000/' });
const app = createApp({ url: 'http://localhost:8000/' })
const renderer = createRenderer({
template: readFileSync('./index.template.html', 'utf-8')
});
})
const context = {
title: 'Hello',
meta: `
<meta name="description" content="Vue.js SSR Example">
`
};
}
renderer.renderToString(app, (err, html) => {
if (err) throw err;
const res: string = html;
});
if (err) throw err
const res: string = html
})
renderer.renderToString(app, context, (err, html) => {
if (err) throw err;
const res: string = html;
});
if (err) throw err
const res: string = html
})
renderer.renderToString(app)
renderer
.renderToString(app)
.then(html => {
const res: string = html;
const res: string = html
})
.catch(err => {
throw err;
});
throw err
})
renderer.renderToString(app, context)
renderer
.renderToString(app, context)
.then(html => {
const res: string = html;
const res: string = html
})
.catch(err => {
throw err;
});
throw err
})
renderer.renderToStream(app, context).on('data', chunk => {
const html = chunk.toString();
});
const html = chunk.toString()
})
// Bundle renderer test
declare const cacheClient: { [key: string]: string };
declare const cacheClient: { [key: string]: string }
const bundleRenderer = createBundleRenderer('/path/to/vue-ssr-server-bundle.json', {
inject: false,
runInNewContext: 'once',
basedir: '/path/to/base',
const bundleRenderer = createBundleRenderer(
'/path/to/vue-ssr-server-bundle.json',
{
inject: false,
runInNewContext: 'once',
basedir: '/path/to/base',
shouldPreload: (file, type) => {
if (type === 'script' || type === 'style') {
return true;
}
if (type === 'font') {
return /\.woff2$/.test(file);
}
if (type === 'image') {
return file === 'hero.jpg';
}
return false;
},
cache: {
get: key => {
return cacheClient[key];
shouldPreload: (file, type) => {
if (type === 'script' || type === 'style') {
return true
}
if (type === 'font') {
return /\.woff2$/.test(file)
}
if (type === 'image') {
return file === 'hero.jpg'
}
return false
},
set: (key, val) => {
cacheClient[key] = val;
},
has: key => {
return !!cacheClient[key];
}
},
directives: {
example (vnode: VNode, directiveMeta: VNodeDirective) {
// transform vnode based on directive binding metadata
cache: {
get: key => {
return cacheClient[key]
},
set: (key, val) => {
cacheClient[key] = val
},
has: key => {
return !!cacheClient[key]
}
},
directives: {
example(vnode: VNode, directiveMeta: VNodeDirective) {
// transform vnode based on directive binding metadata
}
}
}
});
)
bundleRenderer.renderToString(context, (err, html) => {
if (err) throw err;
const res: string = html;
});
if (err) throw err
const res: string = html
})
bundleRenderer.renderToString().then(html => {
const res: string = html;
});
const res: string = html
})
bundleRenderer.renderToString(context).then(html => {
const res: string = html;
});
const res: string = html
})
bundleRenderer.renderToStream(context).on('data', chunk => {
const html = chunk.toString();
});
const html = chunk.toString()
})
// webpack plugins
webpack({
@ -125,4 +133,4 @@ webpack({
filename: 'server-bundle.json'
})
]
});
})

View File

@ -1,7 +1,7 @@
const vm = new Vue({
template: "<div>hi</div>"
});
template: '<div>hi</div>'
})
const options: Vue.ComponentOptions<Vue> = {
template: "<div>test</div>"
};
template: '<div>test</div>'
}

View File

@ -1,79 +1,82 @@
import Vue, { VNode } from "../index";
import { ComponentOptions } from "../options";
import Vue, { VNode } from '../index'
import { ComponentOptions } from '../options'
class Test extends Vue {
a: number = 0;
a: number = 0
testProperties() {
this.$data;
this.$el;
this.$options;
this.$parent;
this.$root;
this.$children;
this.$refs;
this.$slots;
this.$isServer;
this.$ssrContext;
this.$vnode;
this.$data
this.$el
this.$options
this.$parent
this.$root
this.$children
this.$refs
this.$slots
this.$isServer
this.$ssrContext
this.$vnode
}
// test property reification
$el!: HTMLElement | SVGElement;
$el!: HTMLElement | SVGElement
$refs!: {
vue: Vue,
element: HTMLInputElement,
vues: Vue[],
vue: Vue
element: HTMLInputElement
vues: Vue[]
elements: HTMLInputElement[]
}
testReification() {
this.$refs.vue.$data;
this.$refs.element.value;
this.$refs.vues[0].$data;
this.$refs.elements[0].value;
this.$refs.vue.$data
this.$refs.element.value
this.$refs.vues[0].$data
this.$refs.elements[0].value
}
testMethods() {
this.$mount("#app", false);
this.$forceUpdate();
this.$destroy();
this.$set({}, "key", "value");
this.$delete({}, "key");
this.$watch("a", (val: number, oldVal: number) => {}, {
this.$mount('#app', false)
this.$forceUpdate()
this.$destroy()
this.$set({}, 'key', 'value')
this.$delete({}, 'key')
this.$watch('a', (val: number, oldVal: number) => {}, {
immediate: true,
deep: false
})();
this.$watch(() => this.a, (val: number) => {});
this.$on("", () => {});
this.$once("", () => {});
this.$off("", () => {});
this.$emit("", 1, 2, 3);
this.$nextTick(function() {
this.$nextTick;
});
this.$nextTick().then(() => {});
this.$createElement("div", {}, "message");
})()
this.$watch(
() => this.a,
(val: number) => {}
)
this.$on('', () => {})
this.$once('', () => {})
this.$off('', () => {})
this.$emit('', 1, 2, 3)
this.$nextTick(function () {
this.$nextTick
})
this.$nextTick().then(() => {})
this.$createElement('div', {}, 'message')
}
static testConfig() {
const { config } = this;
config.silent;
config.optionMergeStrategies;
config.devtools;
const { config } = this
config.silent
config.optionMergeStrategies
config.devtools
config.errorHandler = (err, vm) => {
if (vm instanceof Test) {
vm.testProperties();
vm.testMethods();
vm.testProperties()
vm.testMethods()
}
};
}
config.warnHandler = (msg, vm) => {
if (vm instanceof Test) {
vm.testProperties();
vm.testMethods();
vm.testProperties()
vm.testMethods()
}
};
config.keyCodes = { esc: 27 };
config.ignoredElements = ['foo', /^ion-/];
}
config.keyCodes = { esc: 27 }
config.ignoredElements = ['foo', /^ion-/]
config.async = false
}
@ -81,108 +84,114 @@ class Test extends Vue {
this.extend({
data() {
return {
msg: ""
};
msg: ''
}
}
});
this.nextTick(() => {});
this.nextTick(function () {
console.log(this.text === 'test');
}, { text: 'test'});
this.nextTick().then(() => {});
this.set({}, "", "");
this.set({}, 1, "");
this.set([true, false, true], 1, true);
this.delete({}, "");
this.delete({}, 1);
this.delete([true, false], 0);
this.directive("", {bind() {}});
this.filter("", (value: number) => value);
this.component("", { data: () => ({}) });
this.component("", { functional: true, render(h) { return h("div", "hello!") } });
this.use;
this.mixin(Test);
this.compile("<div>{{ message }}</div>");
this
.use(() => {
})
.use(() => {
})
})
this.nextTick(() => {})
this.nextTick(
function () {
console.log(this.text === 'test')
},
{ text: 'test' }
)
this.nextTick().then(() => {})
this.set({}, '', '')
this.set({}, 1, '')
this.set([true, false, true], 1, true)
this.delete({}, '')
this.delete({}, 1)
this.delete([true, false], 0)
this.directive('', { bind() {} })
this.filter('', (value: number) => value)
this.component('', { data: () => ({}) })
this.component('', {
functional: true,
render(h) {
return h('div', 'hello!')
}
})
this.use
this.mixin(Test)
this.compile('<div>{{ message }}</div>')
this.use(() => {})
.use(() => {})
.mixin({})
.mixin({})
.mixin({});
}
}
const HelloWorldComponent = Vue.extend({
props: ["name"],
props: ['name'],
data() {
return {
message: "Hello " + this.name,
message: 'Hello ' + this.name
}
},
computed: {
shouted(): string {
return this.message.toUpperCase();
return this.message.toUpperCase()
}
},
methods: {
getMoreExcited() {
this.message += "!";
this.message += '!'
}
},
watch: {
message(a: string) {
console.log(`Message ${this.message} was changed!`);
console.log(`Message ${this.message} was changed!`)
}
}
});
})
const FunctionalHelloWorldComponent = Vue.extend({
functional: true,
props: ["name"],
props: ['name'],
render(createElement, ctxt) {
return createElement("div", "Hello " + ctxt.props.name)
return createElement('div', 'Hello ' + ctxt.props.name)
}
});
})
const FunctionalScopedSlotsComponent = Vue.extend({
functional: true,
render(h, ctx) {
return ctx.scopedSlots.default && ctx.scopedSlots.default({}) || h('div', 'functional scoped slots');
return (
(ctx.scopedSlots.default && ctx.scopedSlots.default({})) ||
h('div', 'functional scoped slots')
)
}
});
})
const Parent = Vue.extend({
data() {
return { greeting: 'Hello' }
}
});
})
const Child = Parent.extend({
methods: {
foo() {
console.log(this.greeting.toLowerCase());
console.log(this.greeting.toLowerCase())
}
}
});
})
const GrandChild = Child.extend({
computed: {
lower(): string {
return this.greeting.toLowerCase();
return this.greeting.toLowerCase()
}
}
});
})
new GrandChild().lower.toUpperCase();
for (let _ in (new Test()).$options) {
new GrandChild().lower.toUpperCase()
for (let _ in new Test().$options) {
}
declare const options: ComponentOptions<Vue>;
Vue.extend(options);
Vue.component('test-comp', options);
new Vue(options);
declare const options: ComponentOptions<Vue>
Vue.extend(options)
Vue.component('test-comp', options)
new Vue(options)
// cyclic example
Vue.extend({
@ -194,21 +203,21 @@ Vue.extend({
methods: {
foo() {}
},
mounted () {
mounted() {
this.foo()
},
// manual annotation
render (h): VNode {
render(h): VNode {
const a = this.bar
return h('canvas', {}, [a])
}
})
declare function decorate<VC extends typeof Vue>(v: VC): VC;
declare function decorate<VC extends typeof Vue>(v: VC): VC
@decorate
class Decorated extends Vue {
a = 123;
a = 123
}
const obj = Vue.observable({ a: 1 })
@ -216,25 +225,23 @@ obj.a++
// VNodeData style tests.
const ComponentWithStyleInVNodeData = Vue.extend({
render (h) {
render(h) {
const elementWithStyleAsString = h('div', {
style: 'background-color: red;'
});
})
const elementWithStyleAsObject = h('div', {
style: { backgroundColor: 'green' }
});
})
const elementWithStyleAsArrayOfObjects = h('div', {
style: [
{ backgroundColor: 'blue' }
]
});
style: [{ backgroundColor: 'blue' }]
})
return h('div', undefined, [
elementWithStyleAsString,
elementWithStyleAsObject,
elementWithStyleAsArrayOfObjects
]);
])
}
});
})

74
types/umd.d.ts vendored
View File

@ -1,48 +1,68 @@
import * as V from "./index";
import * as V from './index'
import {
DefaultData,
DefaultProps,
DefaultMethods,
DefaultComputed,
PropsDefinition
} from "./options";
} from './options'
// Expose some types for backward compatibility...
declare namespace Vue {
// vue.d.ts
export type CreateElement = V.CreateElement;
export type VueConstructor<V extends Vue = Vue> = V.VueConstructor<V>;
export type CreateElement = V.CreateElement
export type VueConstructor<V extends Vue = Vue> = V.VueConstructor<V>
// options.d.ts
export type Component<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = V.Component<Data, Methods, Computed, Props>;
export type AsyncComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> = V.AsyncComponent<Data, Methods, Computed, Props>;
export type ComponentOptions<V extends Vue, Data=DefaultData<V>, Methods=DefaultMethods<V>, Computed=DefaultComputed, PropsDef=PropsDefinition<DefaultProps>, Props=DefaultProps> = V.ComponentOptions<V, Data, Methods, Computed, PropsDef, Props>;
export type FunctionalComponentOptions<Props = DefaultProps, PropDefs = PropsDefinition<Props>> = V.FunctionalComponentOptions<Props, PropDefs>;
export type RenderContext<Props=DefaultProps> = V.RenderContext<Props>;
export type PropType<T> = V.PropType<T>;
export type PropOptions<T=any> = V.PropOptions<T>;
export type ComputedOptions<T> = V.ComputedOptions<T>;
export type WatchHandler<T> = V.WatchHandler<T>;
export type WatchOptions = V.WatchOptions;
export type WatchOptionsWithHandler<T> = V.WatchOptionsWithHandler<T>;
export type DirectiveFunction = V.DirectiveFunction;
export type DirectiveOptions = V.DirectiveOptions;
export type Component<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps
> = V.Component<Data, Methods, Computed, Props>
export type AsyncComponent<
Data = DefaultData<never>,
Methods = DefaultMethods<never>,
Computed = DefaultComputed,
Props = DefaultProps
> = V.AsyncComponent<Data, Methods, Computed, Props>
export type ComponentOptions<
V extends Vue,
Data = DefaultData<V>,
Methods = DefaultMethods<V>,
Computed = DefaultComputed,
PropsDef = PropsDefinition<DefaultProps>,
Props = DefaultProps
> = V.ComponentOptions<V, Data, Methods, Computed, PropsDef, Props>
export type FunctionalComponentOptions<
Props = DefaultProps,
PropDefs = PropsDefinition<Props>
> = V.FunctionalComponentOptions<Props, PropDefs>
export type RenderContext<Props = DefaultProps> = V.RenderContext<Props>
export type PropType<T> = V.PropType<T>
export type PropOptions<T = any> = V.PropOptions<T>
export type ComputedOptions<T> = V.ComputedOptions<T>
export type WatchHandler<T> = V.WatchHandler<T>
export type WatchOptions = V.WatchOptions
export type WatchOptionsWithHandler<T> = V.WatchOptionsWithHandler<T>
export type DirectiveFunction = V.DirectiveFunction
export type DirectiveOptions = V.DirectiveOptions
// plugin.d.ts
export type PluginFunction<T> = V.PluginFunction<T>;
export type PluginObject<T> = V.PluginObject<T>;
export type PluginFunction<T> = V.PluginFunction<T>
export type PluginObject<T> = V.PluginObject<T>
// vnode.d.ts
export type VNodeChildren = V.VNodeChildren;
export type VNodeChildrenArrayContents = V.VNodeChildrenArrayContents;
export type VNode = V.VNode;
export type VNodeComponentOptions = V.VNodeComponentOptions;
export type VNodeData = V.VNodeData;
export type VNodeDirective = V.VNodeDirective;
export type VNodeChildren = V.VNodeChildren
export type VNodeChildrenArrayContents = V.VNodeChildrenArrayContents
export type VNode = V.VNode
export type VNodeComponentOptions = V.VNodeComponentOptions
export type VNodeData = V.VNodeData
export type VNodeDirective = V.VNodeDirective
}
declare class Vue extends V.default {}
export = Vue;
export = Vue
export as namespace Vue;
export as namespace Vue

13
types/v3.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
import { VNode } from './vnode'
import { CreateElement, Vue } from './vue'
export interface SetupContext {
attrs: Record<string, any>
slots: Record<string, (() => VNode[]) | undefined>
emit: (event: string, ...args: any[]) => any
expose: (exposed?: Record<string, any>) => void
}
export function getCurrentInstance(): { proxy: Vue } | null
export const h: CreateElement

127
types/vnode.d.ts vendored
View File

@ -1,76 +1,89 @@
import { Vue } from "./vue";
import { Vue } from './vue'
export type ScopedSlot = (props: any) => ScopedSlotReturnValue;
type ScopedSlotReturnValue = VNode | string | boolean | null | undefined | ScopedSlotReturnArray;
export type ScopedSlot = (props: any) => ScopedSlotReturnValue
type ScopedSlotReturnValue =
| VNode
| string
| boolean
| null
| undefined
| ScopedSlotReturnArray
interface ScopedSlotReturnArray extends Array<ScopedSlotReturnValue> {}
// Scoped slots are guaranteed to return Array of VNodes starting in 2.6
export type NormalizedScopedSlot = (props: any) => ScopedSlotChildren;
export type ScopedSlotChildren = VNode[] | undefined;
export type NormalizedScopedSlot = (props: any) => ScopedSlotChildren
export type ScopedSlotChildren = VNode[] | undefined
// Relaxed type compatible with $createElement
export type VNodeChildren = VNodeChildrenArrayContents | [ScopedSlot] | string | boolean | null | undefined;
export interface VNodeChildrenArrayContents extends Array<VNodeChildren | VNode> {}
export type VNodeChildren =
| VNodeChildrenArrayContents
| [ScopedSlot]
| string
| boolean
| null
| undefined
export interface VNodeChildrenArrayContents
extends Array<VNodeChildren | VNode> {}
export interface VNode {
tag?: string;
data?: VNodeData;
children?: VNode[];
text?: string;
elm?: Node;
ns?: string;
context?: Vue;
key?: string | number | symbol | boolean;
componentOptions?: VNodeComponentOptions;
componentInstance?: Vue;
parent?: VNode;
raw?: boolean;
isStatic?: boolean;
isRootInsert: boolean;
isComment: boolean;
tag?: string
data?: VNodeData
children?: VNode[]
text?: string
elm?: Node
ns?: string
context?: Vue
key?: string | number | symbol | boolean
componentOptions?: VNodeComponentOptions
componentInstance?: Vue
parent?: VNode
raw?: boolean
isStatic?: boolean
isRootInsert: boolean
isComment: boolean
}
export interface VNodeComponentOptions {
Ctor: typeof Vue;
propsData?: object;
listeners?: object;
children?: VNode[];
tag?: string;
Ctor: typeof Vue
propsData?: object
listeners?: object
children?: VNode[]
tag?: string
}
export interface VNodeData {
key?: string | number;
slot?: string;
scopedSlots?: { [key: string]: ScopedSlot | undefined };
ref?: string;
refInFor?: boolean;
tag?: string;
staticClass?: string;
class?: any;
staticStyle?: { [key: string]: any };
style?: string | object[] | object;
props?: { [key: string]: any };
attrs?: { [key: string]: any };
domProps?: { [key: string]: any };
hook?: { [key: string]: Function };
on?: { [key: string]: Function | Function[] };
nativeOn?: { [key: string]: Function | Function[] };
transition?: object;
show?: boolean;
key?: string | number
slot?: string
scopedSlots?: { [key: string]: ScopedSlot | undefined }
ref?: string
refInFor?: boolean
tag?: string
staticClass?: string
class?: any
staticStyle?: { [key: string]: any }
style?: string | object[] | object
props?: { [key: string]: any }
attrs?: { [key: string]: any }
domProps?: { [key: string]: any }
hook?: { [key: string]: Function }
on?: { [key: string]: Function | Function[] }
nativeOn?: { [key: string]: Function | Function[] }
transition?: object
show?: boolean
inlineTemplate?: {
render: Function;
staticRenderFns: Function[];
};
directives?: VNodeDirective[];
keepAlive?: boolean;
render: Function
staticRenderFns: Function[]
}
directives?: VNodeDirective[]
keepAlive?: boolean
}
export interface VNodeDirective {
name: string;
value?: any;
oldValue?: any;
expression?: string;
arg?: string;
oldArg?: string;
modifiers?: { [key: string]: boolean };
name: string
value?: any
oldValue?: any
expression?: string
arg?: string
oldArg?: string
modifiers?: { [key: string]: boolean }
}

370
types/vue.d.ts vendored
View File

@ -10,123 +10,327 @@ import {
RecordPropsDefinition,
ThisTypedComponentOptionsWithArrayProps,
ThisTypedComponentOptionsWithRecordProps,
WatchOptions,
} from "./options";
import { VNode, VNodeData, VNodeChildren, NormalizedScopedSlot } from "./vnode";
import { PluginFunction, PluginObject } from "./plugin";
WatchOptions
} from './options'
import { VNode, VNodeData, VNodeChildren, NormalizedScopedSlot } from './vnode'
import { PluginFunction, PluginObject } from './plugin'
export interface CreateElement {
(tag?: string | Component<any, any, any, any> | AsyncComponent<any, any, any, any> | (() => Component), children?: VNodeChildren): VNode;
(tag?: string | Component<any, any, any, any> | AsyncComponent<any, any, any, any> | (() => Component), data?: VNodeData, children?: VNodeChildren): VNode;
(
tag?:
| string
| Component<any, any, any, any>
| AsyncComponent<any, any, any, any>
| (() => Component),
children?: VNodeChildren
): VNode
(
tag?:
| string
| Component<any, any, any, any>
| AsyncComponent<any, any, any, any>
| (() => Component),
data?: VNodeData,
children?: VNodeChildren
): VNode
}
export interface Vue {
readonly $el: Element;
readonly $options: ComponentOptions<Vue>;
readonly $parent: Vue;
readonly $root: Vue;
readonly $children: Vue[];
readonly $refs: { [key: string]: Vue | Element | (Vue | Element)[] | undefined };
readonly $slots: { [key: string]: VNode[] | undefined };
readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined };
readonly $isServer: boolean;
readonly $data: Record<string, any>;
readonly $props: Record<string, any>;
readonly $ssrContext: any;
readonly $vnode: VNode;
readonly $attrs: Record<string, string>;
readonly $listeners: Record<string, Function | Function[]>;
readonly $el: Element
readonly $options: ComponentOptions<Vue>
readonly $parent: Vue
readonly $root: Vue
readonly $children: Vue[]
readonly $refs: {
[key: string]: Vue | Element | (Vue | Element)[] | undefined
}
readonly $slots: { [key: string]: VNode[] | undefined }
readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined }
readonly $isServer: boolean
readonly $data: Record<string, any>
readonly $props: Record<string, any>
readonly $ssrContext: any
readonly $vnode: VNode
readonly $attrs: Record<string, string>
readonly $listeners: Record<string, Function | Function[]>
$mount(elementOrSelector?: Element | string, hydrating?: boolean): this;
$forceUpdate(): void;
$destroy(): void;
$set: typeof Vue.set;
$delete: typeof Vue.delete;
$mount(elementOrSelector?: Element | string, hydrating?: boolean): this
$forceUpdate(): void
$destroy(): void
$set: typeof Vue.set
$delete: typeof Vue.delete
$watch(
expOrFn: string,
callback: (this: this, n: any, o: any) => void,
options?: WatchOptions
): (() => void);
): () => void
$watch<T>(
expOrFn: (this: this) => T,
callback: (this: this, n: T, o: T) => void,
options?: WatchOptions
): (() => void);
$on(event: string | string[], callback: Function): this;
$once(event: string | string[], callback: Function): this;
$off(event?: string | string[], callback?: Function): this;
$emit(event: string, ...args: any[]): this;
$nextTick(callback: (this: this) => void): void;
$nextTick(): Promise<void>;
$createElement: CreateElement;
): () => void
$on(event: string | string[], callback: Function): this
$once(event: string | string[], callback: Function): this
$off(event?: string | string[], callback?: Function): this
$emit(event: string, ...args: any[]): this
$nextTick(callback: (this: this) => void): void
$nextTick(): Promise<void>
$createElement: CreateElement
}
export type CombinedVueInstance<Instance extends Vue, Data, Methods, Computed, Props> = Data & Methods & Computed & Props & Instance;
export type ExtendedVue<Instance extends Vue, Data, Methods, Computed, Props> = VueConstructor<CombinedVueInstance<Instance, Data, Methods, Computed, Props> & Vue>;
export type CombinedVueInstance<
Instance extends Vue,
Data,
Methods,
Computed,
Props,
SetupBindings
> = Data & Methods & Computed & Props & Instance & SetupBindings
export type ExtendedVue<
Instance extends Vue,
Data,
Methods,
Computed,
Props,
SetupBindings
> = VueConstructor<
CombinedVueInstance<Instance, Data, Methods, Computed, Props, SetupBindings> &
Vue
>
export interface VueConfiguration {
silent: boolean;
optionMergeStrategies: any;
devtools: boolean;
productionTip: boolean;
performance: boolean;
errorHandler(err: Error, vm: Vue, info: string): void;
warnHandler(msg: string, vm: Vue, trace: string): void;
ignoredElements: (string | RegExp)[];
keyCodes: { [key: string]: number | number[] };
async: boolean;
silent: boolean
optionMergeStrategies: any
devtools: boolean
productionTip: boolean
performance: boolean
errorHandler(err: Error, vm: Vue, info: string): void
warnHandler(msg: string, vm: Vue, trace: string): void
ignoredElements: (string | RegExp)[]
keyCodes: { [key: string]: number | number[] }
async: boolean
}
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>>;
// ideally, the return type should just contain Props, not Record<keyof Props, any>. But TS requires to have Base constructors with the same return type.
new <Data = object, Methods = object, Computed = object, Props = object>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): CombinedVueInstance<V, Data, Methods, Computed, Record<keyof Props, any>>;
new (options?: ComponentOptions<V>): CombinedVueInstance<V, object, object, object, Record<keyof object, any>>;
/**
* new with array props
*/
new <
Data = object,
Methods = object,
Computed = object,
PropNames extends string = never,
SetupBindings = {}
>(
options?: ThisTypedComponentOptionsWithArrayProps<
V,
Data,
Methods,
Computed,
PropNames,
SetupBindings
>
): CombinedVueInstance<
V,
Data,
Methods,
Computed,
Record<PropNames, any>,
SetupBindings
>
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>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;
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(options?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;
/**
* new with object props
* ideally, the return type should just contain Props,
* not Record<keyof Props, any>. But TS requires to have Base constructors
* with the same return type.
*/
new <
Data = object,
Methods = object,
Computed = object,
Props = object,
SetupBindings = {}
>(
options?: ThisTypedComponentOptionsWithRecordProps<
V,
Data,
Methods,
Computed,
Props,
SetupBindings
>
): CombinedVueInstance<
V,
Data,
Methods,
Computed,
Record<keyof Props, any>,
SetupBindings
>
nextTick<T>(callback: (this: T) => void, context?: T): void;
/**
* new with no props
*/
new (options?: ComponentOptions<V>): CombinedVueInstance<
V,
object,
object,
object,
Record<keyof object, any>,
{}
>
/**
* extend with array props
*/
extend<
Data,
Methods,
Computed,
PropNames extends string = never,
SetupBindings = {}
>(
options?: ThisTypedComponentOptionsWithArrayProps<
V,
Data,
Methods,
Computed,
PropNames,
SetupBindings
>
): ExtendedVue<
V,
Data,
Methods,
Computed,
Record<PropNames, any>,
SetupBindings
>
/**
* extend with object props
*/
extend<Data, Methods, Computed, Props, SetupBindings = {}>(
options?: ThisTypedComponentOptionsWithRecordProps<
V,
Data,
Methods,
Computed,
Props,
SetupBindings
>
): ExtendedVue<V, Data, Methods, Computed, Props, SetupBindings>
/**
* extend with functional + array props
*/
extend<PropNames extends string = never>(
definition: FunctionalComponentOptions<Record<PropNames, any>, PropNames[]>
): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>, {}>
/**
* extend with functional + object props
*/
extend<Props>(
definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>
): ExtendedVue<V, {}, {}, {}, Props, {}>
/**
* extend with no props
*/
extend(options?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}, {}>
nextTick<T>(callback: (this: T) => void, context?: T): void
nextTick(): Promise<void>
set<T>(object: object, key: string | number, value: T): T;
set<T>(array: T[], key: number, value: T): T;
delete(object: object, key: string | number): void;
delete<T>(array: T[], key: number): void;
set<T>(object: object, key: string | number, value: T): T
set<T>(array: T[], key: number, value: T): T
delete(object: object, key: string | number): void
delete<T>(array: T[], key: number): void
directive(
id: string,
definition?: DirectiveOptions | DirectiveFunction
): DirectiveOptions;
filter(id: string, definition?: Function): Function;
): DirectiveOptions
filter(id: string, definition?: Function): Function
component(id: string): VueConstructor;
component<VC extends VueConstructor>(id: string, constructor: VC): VC;
component<Data, Methods, Computed, Props>(id: string, definition: AsyncComponent<Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;
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>(id: string, definition?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;
component<PropNames extends string>(id: string, definition: FunctionalComponentOptions<Record<PropNames, any>, PropNames[]>): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>>;
component<Props>(id: string, definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;
component(id: string, definition?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;
component(id: string): VueConstructor
component<VC extends VueConstructor>(id: string, constructor: VC): VC
component<Data, Methods, Computed, Props, SetupBindings>(
id: string,
definition: AsyncComponent<Data, Methods, Computed, Props>
): ExtendedVue<V, Data, Methods, Computed, Props, SetupBindings>
component<
Data,
Methods,
Computed,
PropNames extends string = never,
SetupBindings = {}
>(
id: string,
definition?: ThisTypedComponentOptionsWithArrayProps<
V,
Data,
Methods,
Computed,
PropNames,
SetupBindings
>
): ExtendedVue<
V,
Data,
Methods,
Computed,
Record<PropNames, any>,
SetupBindings
>
component<Data, Methods, Computed, Props, SetupBindings>(
id: string,
definition?: ThisTypedComponentOptionsWithRecordProps<
V,
Data,
Methods,
Computed,
Props,
SetupBindings
>
): ExtendedVue<V, Data, Methods, Computed, Props, SetupBindings>
component<PropNames extends string>(
id: string,
definition: FunctionalComponentOptions<Record<PropNames, any>, PropNames[]>
): ExtendedVue<V, {}, {}, {}, Record<PropNames, any>, {}>
component<Props>(
id: string,
definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>
): ExtendedVue<V, {}, {}, {}, Props, {}>
component(
id: string,
definition?: ComponentOptions<V>
): ExtendedVue<V, {}, {}, {}, {}, {}>
use<T>(plugin: PluginObject<T> | PluginFunction<T>, options?: T): VueConstructor<V>;
use(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): VueConstructor<V>;
mixin(mixin: VueConstructor | ComponentOptions<Vue>): VueConstructor<V>;
use<T>(
plugin: PluginObject<T> | PluginFunction<T>,
options?: T
): VueConstructor<V>
use(
plugin: PluginObject<any> | PluginFunction<any>,
...options: any[]
): VueConstructor<V>
mixin(mixin: VueConstructor | ComponentOptions<Vue>): VueConstructor<V>
compile(template: string): {
render(createElement: typeof Vue.prototype.$createElement): VNode;
staticRenderFns: (() => VNode)[];
};
render(createElement: typeof Vue.prototype.$createElement): VNode
staticRenderFns: (() => VNode)[]
}
observable<T>(obj: T): T;
observable<T>(obj: T): T
util: {
warn(msg: string, vm?: InstanceType<VueConstructor>): void;
};
warn(msg: string, vm?: InstanceType<VueConstructor>): void
}
config: VueConfiguration;
version: string;
config: VueConfiguration
version: string
}
export const Vue: VueConstructor;
export const Vue: VueConstructor