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

Typescript Module Declarations #199

Closed
alexsasharegan opened this issue May 4, 2019 · 9 comments
Closed

Typescript Module Declarations #199

alexsasharegan opened this issue May 4, 2019 · 9 comments

Comments

@alexsasharegan
Copy link
Contributor

alexsasharegan commented May 4, 2019

If anyone is looking to stub type declarations for this module, I figured it might be good to have an issue that people can reference.

// Type definitions for vue-virtual-scroller
// Project: https://github.com/Akryum/vue-virtual-scroller/
declare module "vue-virtual-scroller" {
    import Vue, { ComponentOptions, PluginObject, Component } from "vue";
    interface PluginOptions {
        installComponents?: boolean;
        componentsPrefix?: string;
    }

    const plugin: PluginObject<PluginOptions> & { version: string };

    export const RecycleScroller: Component<any, any, any, any>;
    export const DynamicScroller: Component<any, any, any, any>;
    export const DynamicScrollerItem: Component<any, any, any, any>;

    export function IdState(options?: {
        idProp?: (vm: any) => any;
    }): ComponentOptions<Vue> | typeof Vue;

    export default plugin;
}
@alexsasharegan
Copy link
Contributor Author

I've updated the type definition to what appears to be a full working definition. Since this is more of an informational issue, I'll go ahead and close it.

@e-cloud
Copy link

e-cloud commented May 19, 2019

@alexsasharegan when will it be release?

/cc @Akryum

@alexsasharegan
Copy link
Contributor Author

I just applied the definition locally to my project. Not every library author feels comfortable publishing types if they aren’t an active typescript user—and I respect that. It can be a source of issues that are out of scope for them.

My goal here was just to provide an easy to find answer to this question. Try placing this code in a lib-defs.d.ts file in your project (or whatever name you prefer).

@SimonPrague
Copy link

Anyone has types for the new version that supports vue 3?

#478

@EarlTP
Copy link

EarlTP commented Jun 20, 2021

Anyone has types for the new version that supports vue 3?

#478

I made this for an Ionic project with Vue 3 and Typescript, starting from alexsasharegan's solution.
Must be installed using the alias: npm install --save @types/vue-virtual-scroller@npm:@earltp/vue-virtual-scroller

@JasonLandbridge
Copy link

Better typing, source:

Copy paste the following in a file named: vue-virtual-scroller.d.ts

// Type definitions for vue-virtual-scroller
// Project: https://github.com/Akryum/vue-virtual-scroller/
declare module 'vue-virtual-scroller' {
  import Vue, { ComponentOptions, PluginObject } from 'vue';

  interface PluginOptions {
    installComponents?: boolean;
    componentsPrefix?: string;
  }

  declare const plugin: PluginObject<PluginOptions> & { version: string };

  export class RecycleScroller extends Vue {
    sizes: Array<{ accumulator: number }>;
    itemSize: number | null;
    totalSize: number;
    ready: boolean;
    emitUpdate: boolean;
    prerender: number;
    pageMode: boolean;
    buffer: number;
    typeField: string;
    sizeField: string;
    minItemSize: number | string | null;
    direction: 'horizontal' | 'vertical';
    pool: Array<{
      item: unknown;
      position: number;
      nr: {
        id: number;
        index: number;
        key: string;
        type: unknown;
        used: boolean;
      };
    }>;

    getScroll(): { start: number; end: number };

    scrollToItem(index: number): void;

    scrollToPosition(position: number);
  }

  export class DynamicScroller extends RecycleScroller {
    minItemSize: number | string;
    vscrollData: {
      active: boolean;
      sizes: Record<string, number>;
      validSizes: object;
      keyField: string;
      simpleArray: boolean;
    };

    $refs: {
      scroller: RecycleScroller;
    };

    onScrollerResize(): void;

    onScrollerVisible(): void;

    forceUpdate(clear?: boolean): void;

    scrollToItem(index: number): void;

    getItemSize(item: object, index?: number): number;

    scrollToBottom(): void;
  }

  export class DynamicScrollerItem extends Vue {

  }

  export default plugin;
}

@Megasu
Copy link

Megasu commented May 22, 2023

It doesn't work very well.

@coooo77
Copy link

coooo77 commented Oct 14, 2023

wrote a simple declaration, but not sure how to define slots

declare module 'vue-virtual-scroller' {
  import type {
    ComponentOptionsMixin,
    ComponentPropsOptions,
    ComputedOptions,
    DefineComponent,
    MethodOptions
  } from 'vue';

  type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[]
    ? ElementType
    : never;

  type RecycleScrollerProps = {
    items: any[];
    direction?: 'vertical' | 'horizontal';
    itemSize?: number | null;
    gridItems?: number;
    itemSecondarySize?: number;
    minItemSize?: number;
    sizeField?: string;
    typeField?: string;
    keyField?: string;
    pageMode?: boolean;
    prerender?: number;
    buffer?: number;
    emitUpdate?: boolean;
    updateInterval?: number;
    listClass?: string;
    itemClass?: string;
    listTag?: string;
    itemTag?: string;
  };

  type RecycleScrollerEmits = 'resize' | 'visible' | 'hidden' | 'update' | 'scroll-start' | 'scroll-end';

  type RecycleScrollerEmitFunctions = {
    resize: () => void;
    visible: () => void;
    hidden: () => void;
    update: (tartIndex: number, endIndex: number, visibleStartIndex: number, visibleEndIndex: number) => void;
    'scroll-start': () => void;
    'scroll-end': () => void;
  };

  type RecycleScrollerSlotProps = {
    item: ArrayElement<RecycleScrollerProps['items']>;
    index: number;
    active: boolean;
  };

  type RecycleScrollerSlots = {
    default: (slotProps: any) => VNode[];
    before: () => VNode[];
    empty: () => VNode[];
    after: () => VNode[];
  };

  interface RecycleScrollerPublicMethods extends MethodOptions {
    getScroll(): { start: number; end: number };
    scrollToItem(index: number): void;
    scrollToPosition(position: number);
  }

  export const RecycleScroller: DefineComponent<
    ComponentPropsOptions<RecycleScrollerProps>,
    object,
    object,
    ComputedOptions,
    RecycleScrollerPublicMethods,
    ComponentOptionsMixin,
    ComponentOptionsMixin,
    RecycleScrollerEmitFunctions,
    RecycleScrollerEmits,
    RecycleScrollerProps
  >;

  export const DynamicScroller: RecycleScroller;

  type DynamicScrollerItemProps = {
    item: any;
    active: boolean;
    sizeDependencies?: any[];
    watchData?: boolean;
    tag?: string;
    emitResize?: boolean;
    onResize: () => void;
  };

  type DynamicScrollerItemEmits = 'resize';

  export const DynamicScrollerItem: DefineComponent<
    ComponentPropsOptions<DynamicScrollerItemProps>,
    object,
    object,
    ComputedOptions,
    MethodOptions,
    ComponentOptionsMixin,
    ComponentOptionsMixin,
    DynamicScrollerItemEmits[],
    DynamicScrollerItemEmits,
    DynamicScrollerItemProps
  >;
}

@c-harding
Copy link

Here’s a version for Vue 3 that works with scoped slots (based on @coooo77’s solution, thank you!). Note that InstanceType<typeof DynamicScroller> won’t work (bug: vuejs/core#8373), so, when referrring to the instance, I recommend ref<RecycleScrollerInstance>();. I have also not tested IdState, because Mixins are not best practice for Vue 3.

declare module 'vue-virtual-scroller' {
  import {
    type ObjectEmitsOptions,
    type PublicProps,
    type SetupContext,
    type SlotsType,
    type VNode,
  } from 'vue';

  interface RecycleScrollerProps<T> {
    items: readonly T[];
    direction?: 'vertical' | 'horizontal';
    itemSize?: number | null;
    gridItems?: number;
    itemSecondarySize?: number;
    minItemSize?: number;
    sizeField?: string;
    typeField?: string;
    keyField?: keyof T;
    pageMode?: boolean;
    prerender?: number;
    buffer?: number;
    emitUpdate?: boolean;
    updateInterval?: number;
    listClass?: string;
    itemClass?: string;
    listTag?: string;
    itemTag?: string;
  }

  interface DynamicScrollerProps<T> extends RecycleScrollerProps<T> {
    minItemSize: number;
  }

  interface RecycleScrollerEmitOptions extends ObjectEmitsOptions {
    resize: () => void;
    visible: () => void;
    hidden: () => void;
    update: (
      startIndex: number,
      endIndex: number,
      visibleStartIndex: number,
      visibleEndIndex: number,
    ) => void;
    'scroll-start': () => void;
    'scroll-end': () => void;
  }

  interface RecycleScrollerSlotProps<T> {
    item: T;
    index: number;
    active: boolean;
  }

  interface RecycleScrollerSlots<T> {
    default(slotProps: RecycleScrollerSlotProps<T>): unknown;
    before(): unknown;
    empty(): unknown;
    after(): unknown;
  }

  export interface RecycleScrollerInstance {
    getScroll(): { start: number; end: number };
    scrollToItem(index: number): void;
    scrollToPosition(position: number): void;
  }

  export const RecycleScroller: <T>(
    props: RecycleScrollerProps<T> & PublicProps,
    ctx?: SetupContext<RecycleScrollerEmitOptions, SlotsType<RecycleScrollerSlots<T>>>,
    expose?: (exposed: RecycleScrollerInstance) => void,
  ) => VNode & {
    __ctx?: {
      props: RecycleScrollerProps<T> & PublicProps;
      expose(exposed: RecycleScrollerInstance): void;
      slots: RecycleScrollerSlots<T>;
    };
  };

  export const DynamicScroller: <T>(
    props: DynamicScrollerProps<T> & PublicProps,
    ctx?: SetupContext<RecycleScrollerEmitOptions, SlotsType<RecycleScrollerSlots<T>>>,
    expose?: (exposed: RecycleScrollerInstance) => void,
  ) => VNode & {
    __ctx?: {
      props: DynamicScrollerProps<T> & PublicProps;
      expose(exposed: RecycleScrollerInstance): void;
      slots: RecycleScrollerSlots<T>;
    };
  };

  interface DynamicScrollerItemProps<T> {
    item: T;
    active: boolean;
    sizeDependencies?: unknown[];
    watchData?: boolean;
    tag?: string;
    emitResize?: boolean;
    onResize?: () => void;
  }

  interface DynamicScrollerItemEmitOptions extends ObjectEmitsOptions {
    resize: () => void;
  }

  export const DynamicScrollerItem: <T>(
    props: DynamicScrollerItemProps<T> & PublicProps,
    ctx?: SetupContext<DynamicScrollerItemEmitOptions>,
  ) => VNode;

  export function IdState(options?: { idProp?: (value: any) => unknown }): ComponentOptionsMixin;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants