1

Getting the error

error TS2304: Cannot find name 'ClipboardItem'

when trying to create a ClipboardItem for navigator.clipboard.write().

const clipboardItemInput = new ClipboardItem({'image/png' : blobInput});
 await navigator.clipboard.write([clipboardItemInput]);

I am using Angular 6. Do I need to add any dependencies, or is there any other method?

Oleg Valter
  • 6,098
  • 6
  • 22
  • 37

2 Answers2

2

The Typescript version might not incorporate all the features. This is where we need to extend it by creating typings or extending the existing ones. To solve the issue, try to create a types.d.ts file (reference1) and put the following in it:

declare class ClipboardItem {
  constructor(data: { [mimeType: string]: Blob });
}

Then reference the file in your component code with:

/// <reference path="types.d.ts" />

Then feel free to use the Class.

const item = new ClipboardItem({ "image/png": blob });
window.navigator['clipboard'].write([item]);

Inspiration: reference2

Nico S.
  • 21
  • 3
0

As of 2021, the TypeScript standard library is still missing a definition for the Clipboard API (and that is the reason for the "Cannot find name 'ClipboardItem'" error). There is an open issue on the source repository and a pull request on the DOM lib generator repository (because the standard library is autogenerated) that should address the issue.

In the meantime, you can add the following definitions matching how the standard library defines other global interfaces (do not forget to add a triple-slash directive /// <reference types="../../index" /> at the top of the importing file):

interface ClipboardItem {
  readonly types: string[];
  readonly presentationStyle: "unspecified" | "inline" | "attachment";
  getType(): Promise<Blob>;
}

interface ClipboardItemData {
  [mimeType: string]: Blob | string | Promise<Blob | string>;
}

declare var ClipboardItem: {
  prototype: ClipboardItem;
  new (itemData: ClipboardItemData): ClipboardItem;
};

Note that the ClipboardItemData is defined to take either Blob, string, or a promise that returns one of the former and not just a Blob (see the MDN reference, for example). It also does not hurt to augment the Clipboard interface with missing read and write methods:

interface Clipboard {
  read(): Promise<DataTransfer>;
  write(data: ClipboardItem[]): Promise<void>;
}

Finally, let's test that the definitions work as expected:

declare const image: Blob;
(async () => {
  const item = new ClipboardItem({ ["image/png"]: image });

  const { files } = await navigator.clipboard.read();
  if( files.length ) return;

  await navigator.clipboard.write([item]);
})();

Playground

Oleg Valter
  • 6,098
  • 6
  • 22
  • 37