1valdis
1valdis

Reputation: 1104

Extend globally declared Type in Typescript

Background:

I'm creating an app that will work with Permissions and Clipboard API. Standard Typescript library doesn't have typings for much of cutting-edge Clipboard API stuff, so I went to create a .d.ts file to extend such incomplete interfaces. It contains declarations like that:

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

and I reference it from my code this way: /// <reference path="clipboard.d.ts" />

So far so good: absent interfaces are getting added, existing ones get extended, autocompletion is working correctly. But then I came to requesting "clipboard-read" permission. I want to pass this string when calling navigator.permissions.query({name: "clipboard-read"}) where name's type is defined in standard Typescript library as follows:

type PermissionName = "geolocation" |  ... | "clipboard";

And it doesn't have "clipboard-read" there. So I want to extend it so that it includes "clipboard-read". Now, if in my .d.ts file I write

type PermissionName = 'clipboard-read';

it shows me an error Duplicate identifier 'PermissionName'.ts(2300). I tried other varieties but all of them came down to Duplicate identifier error.

Question:

Is there a way to extend not an interface, but a type that was already globally declared elsewhere? What should I do to achieve that?

Upvotes: 5

Views: 2656

Answers (1)

255kb - Mockoon
255kb - Mockoon

Reputation: 6974

As far as I know, you cannot "override" an existing type with Typescript. You could modify the lib/dom.d.ts file in the node_modules folder but it's definitely not a good option in my opinion.

The only viable solution I see is to cast:

navigator.permissions.query({name: 'clipboard-write' as PermissionName});

or to create a custom type and a wrapping method (which will casts):

type  MyPermissionName = PermissionName | 'clipboard-read' | 'clipboard-write';

function requestPermission(permission: MyPermissionName) {
  return navigator.permissions.query({name: permission as PermissionName});
}

Upvotes: 10

Related Questions