Skip to content
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

types(Vue.use): fix #10573, better Vue.use type inference #11351

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
feat: advanced-inferance
  • Loading branch information
IWANABETHATGUY committed Apr 29, 2020
commit ef5f9621a0b826e46c223dc857356f1de1a2f3bb
11 changes: 8 additions & 3 deletions types/plugin.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { Vue as _Vue } from "./vue";

export type PluginFunction<T> = (Vue: typeof _Vue, options?: T) => void;
type GetPluginRestParams<T> = T extends PluginFunction ? getTupleType<T> : T extends PluginObject ? getTupleType<T['install']> : [];
type getTupleType<T> = T extends (vue: typeof _Vue, ...rest: infer T) => void ? T : never
type Assert<T, U> = T extends U ? T : never;

export interface PluginObject<T> {
install: PluginFunction<T>;
export type PluginFunction = (Vue: typeof _Vue, ...options: any[]) => void;
export type RestParams<T> = Assert<GetPluginRestParams<T>, any[]>;

export interface PluginObject {
install: PluginFunction;
[key: string]: any;
}
12 changes: 6 additions & 6 deletions types/test/plugin-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ import Vue, { VueConstructor } from "../index";
import { PluginFunction, PluginObject } from "../index";

class Option {
prefix: string = "";
prefix?: string = "";
suffix: string = "";
}

const plugin: PluginObject<Option> = {
const plugin: PluginObject = {
install(Vue, option) {
if (typeof option !== "undefined") {
const {prefix, suffix} = option;
}
}
}
const installer: PluginFunction<Option> = function(Vue, option) { }
const installer: PluginFunction = function(Vue, option) { }
function NoOptions( _Vue: VueConstructor<Vue>){};
function OptionalOption( _Vue: VueConstructor<Vue>, options?: Option) {};
function OptionalOption( _Vue: VueConstructor<Vue>, options?: Option, other?: Option, another?: Option) {};

Vue.use(NoOptions);
Vue.use(OptionalOption, {prefix: 'prefix', suffix: 'suffix'});
Vue.use(OptionalOption, {prefix: '', suffix: ''}, {prefix: '', suffix: ''}, { suffix: ''});
Vue.use(OptionalOption);

Vue.use(plugin);
Vue.use(installer, new Option);
Vue.use(installer, new Option, new Option);
Vue.use(installer, new Option, new Option, new Option);
4 changes: 2 additions & 2 deletions types/vue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
WatchOptions,
} from "./options";
import { VNode, VNodeData, VNodeChildren, NormalizedScopedSlot } from "./vnode";
import { PluginFunction, PluginObject } from "./plugin";
import { PluginFunction, PluginObject, RestParams } from "./plugin";

export interface CreateElement {
(tag?: string | Component<any, any, any, any> | AsyncComponent<any, any, any, any> | (() => Component), children?: VNodeChildren): VNode;
Expand Down Expand Up @@ -111,7 +111,7 @@ export interface VueConstructor<V extends Vue = Vue> {
component<Props>(id: string, definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;
component(id: string, definition?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;

use<T = any>(plugin: PluginObject<T> | PluginFunction<T>, option?: T, ...rest: any[]): VueConstructor<V>;
use<T extends PluginObject | PluginFunction>(plugin: T, ...rest: RestParams<T>): VueConstructor<V>;
mixin(mixin: VueConstructor | ComponentOptions<Vue>): VueConstructor<V>;
compile(template: string): {
render(createElement: typeof Vue.prototype.$createElement): VNode;
Expand Down