Vue.draggable: Any Plans on including TypeScript definitions?

Created on 25 Mar 2018  路  13Comments  路  Source: SortableJS/Vue.Draggable

Any plans on including TypeScript definitions?

enhancement

Most helpful comment

This might not be comprehensive (I didn't want to spend much time on this), but here's the type declaration I'm using:

declare module 'vuedraggable' {
  import Vue, { ComponentOptions } from 'vue';

  export interface DraggedContext<T> {
    index: number;
    futureIndex: number;
    element: T;
  }

  export interface DropContext<T> {
    index: number;
    component: Vue;
    element: T;
  }

  export interface Rectangle {
    top: number;
    right: number;
    bottom: number;
    left: number;
    width: number;
    height: number;
  }

  export interface MoveEvent<T> {
    originalEvent: DragEvent;
    dragged: Element;
    draggedContext: DraggedContext<T>;
    draggedRect: Rectangle;
    related: Element;
    relatedContext: DropContext<T>;
    relatedRect: Rectangle;
    from: Element;
    to: Element;
    willInsertAfter: boolean;
    isTrusted: boolean;
  }

  const draggableComponent: ComponentOptions<Vue>;

  export default draggableComponent;
}

Create a directory @types/vuedraggable at the root of your project, and save the declaration as @types/vuedraggable/index.d.ts.

In your tsconfig.json, you need to tell the TypeScript compiler to look for type declarations in the local @types directory in your project as well as in node_modules, like:

{
  "compilerOptions": {
    "typeRoots": [
      "./@types",
      "./node_modules/@types"
    ],
   }
}

Then you can use the module in your Vue SFC the same as @alzuma's example:

<script lang="ts">
  import { Component, Vue } from "vue-property-decorator";
  import Draggable from 'vuedraggable';

  @Component({
    components: {
      Draggable
    }
  })
  export default class MyComponent extends Vue {
    ...
  }
</script>

If you have a function for handling the vuedraggable move event you can apply typings to it like this:

<template>
  <Draggable :list="myList" :move="onItemMove">
    ...
  </Draggable>
</template>

<script lang="ts">
  import { Component, Vue } from "vue-property-decorator";
  import Draggable, { MoveEvent } from 'vuedraggable';

  interface MyListItem {
    id: number;
    name: string;
  }

  @Component({
    components: {
      Draggable
    }
  })
  export default class MyComponent extends Vue {
    myList: MyListItem[] = [
      {
        id: 1,
        name: "foo"
      },
      {
        id: 2,
        name: "bar"
      }
    ];

    onItemMove(event: MoveEvent<MyListItem>) {
      const movedItem = event.draggedContext.element; // inferred type is MyListItem
      // do stuff
    }
  }
</script>

All 13 comments

It is not part of my plan. But if someone is interested in submiting a PR....

I'll see if I can get the time to do this.

But for now, to make it work with typescript project.

Create a new ts definition file for example "ambient.d.ts"
Add line:
declare module 'vuedraggable';

In your vue file

...
<script lang="ts">
    import {Component, Vue} from "vue-property-decorator";
    import draggable from 'vuedraggable'

    @Component({
        components: {draggable}
    })
    export default class MyComponent extends Vue {
...

Hi Guys,

Does anyone know how I can use draggedContext.element.myProp in typescript. I have the component working but I cannot get the dragged item data like in javascript. It is so frustrating that I cannot get the data. What I am to do is to do something after the item has been dropped but if I cannot get information regarding the dragged item I am doomed.

If anyone can help I would be most grateful.

@alzuma I did declare in ambient.d.ts file. But my import still shows the error "Could not find a declaration file for module 'vuedraggable'" in VS code. Am I supposed to do anything else?

I faced to the same problem. Solution by @alzuma don't work for me.

Facing same issue

This might not be comprehensive (I didn't want to spend much time on this), but here's the type declaration I'm using:

declare module 'vuedraggable' {
  import Vue, { ComponentOptions } from 'vue';

  export interface DraggedContext<T> {
    index: number;
    futureIndex: number;
    element: T;
  }

  export interface DropContext<T> {
    index: number;
    component: Vue;
    element: T;
  }

  export interface Rectangle {
    top: number;
    right: number;
    bottom: number;
    left: number;
    width: number;
    height: number;
  }

  export interface MoveEvent<T> {
    originalEvent: DragEvent;
    dragged: Element;
    draggedContext: DraggedContext<T>;
    draggedRect: Rectangle;
    related: Element;
    relatedContext: DropContext<T>;
    relatedRect: Rectangle;
    from: Element;
    to: Element;
    willInsertAfter: boolean;
    isTrusted: boolean;
  }

  const draggableComponent: ComponentOptions<Vue>;

  export default draggableComponent;
}

Create a directory @types/vuedraggable at the root of your project, and save the declaration as @types/vuedraggable/index.d.ts.

In your tsconfig.json, you need to tell the TypeScript compiler to look for type declarations in the local @types directory in your project as well as in node_modules, like:

{
  "compilerOptions": {
    "typeRoots": [
      "./@types",
      "./node_modules/@types"
    ],
   }
}

Then you can use the module in your Vue SFC the same as @alzuma's example:

<script lang="ts">
  import { Component, Vue } from "vue-property-decorator";
  import Draggable from 'vuedraggable';

  @Component({
    components: {
      Draggable
    }
  })
  export default class MyComponent extends Vue {
    ...
  }
</script>

If you have a function for handling the vuedraggable move event you can apply typings to it like this:

<template>
  <Draggable :list="myList" :move="onItemMove">
    ...
  </Draggable>
</template>

<script lang="ts">
  import { Component, Vue } from "vue-property-decorator";
  import Draggable, { MoveEvent } from 'vuedraggable';

  interface MyListItem {
    id: number;
    name: string;
  }

  @Component({
    components: {
      Draggable
    }
  })
  export default class MyComponent extends Vue {
    myList: MyListItem[] = [
      {
        id: 1,
        name: "foo"
      },
      {
        id: 2,
        name: "bar"
      }
    ];

    onItemMove(event: MoveEvent<MyListItem>) {
      const movedItem = event.draggedContext.element; // inferred type is MyListItem
      // do stuff
    }
  }
</script>

I had to import the source to make it work:

import Draggable from 'vuedraggable/src/vuedraggable.js';

@sgarner I configured everything the way you said and the compiler still says it can't find the declaration file. What you provided makes sense and seems straightforward. Is there anything else different in your tsconfig.json file?

I also have been trying to get this to work for a while. I did the steps that @sgarner suggested and still get the error

Could not find a declaration file for module 'vuedraggable'. '[root dir]/node_modules/vuedraggable/dist/vuedraggable.umd.min.js' implicitly has an 'any' type.

I included the type file in my [root dir]/@types/vuedraggable.d.ts and updated the tsconfig.json file.

@hyerman @pstaabp check the import and export sections of your tsconfig after following @sgarner's suggestions. You may need to add your newly created @types directory like this:

  "include": [
    "@types/**/*.ts",
    "src/**/*.ts",
    "tests/**/*.ts",
  ],

Specifying typeRoots was not necessary in my case.

I did just get this fixed with the suggestion by @till44. That was the key.

Was this page helpful?
0 / 5 - 0 ratings