28

I have a TypeScript project (https://github.com/jmaister/excellentexport) and it is working fine.

After adding the dependabot process, it suggests upgrading typescript:

Bump typescript from 4.3.4 to 4.4.3

However, because the library that I am maintaining has references to Internet Explorer to old Internet Explorer properties, it fails building with the new version.

Here is a sample of the build errors:

src/excellentexport.ts:143:30 - error TS2339: Property 'msSaveBlob' does not exist on type 'Navigator'.
143         if (window.navigator.msSaveBlob) {
                                 ~~~~~~~~~~
src/excellentexport.ts:145:30 - error TS2339: Property 'msSaveBlob' does not exist on type 'Navigator'.
145             window.navigator.msSaveBlob(blob, filename);
                                 ~~~~~~~~~~
src/excellentexport.ts:278:34 - error TS2339: Property 'msSaveBlob' does not exist on type 'Navigator'.

Should I remove the support for old Internet Explorer? Is the a way to continue using those IE specific properties?

2
  • 2
    I would remove support for old IE. They are security nightmares that people need more reasons to let go of. Failing that, it's not TypeScript per se, it's the lib.d.ts and associated files that're bundled with TypeScript that are causing the problem. See github.com/microsoft/TypeScript-DOM-lib-generator/issues/1029 Commented Oct 7, 2021 at 18:11
  • 1
    Whether you should remove IE support depends on whether you/your company want to or have to support it. (Ideally everyone would remove it.) Commented Oct 7, 2021 at 18:12

3 Answers 3

40

I ran into the exact same issue recently, and the solution I arrived at was to extend the Navigator interface in the global namespace so it still includes msSaveBlob, based on how msSaveBlob is documented by TypeScript here: MSFileSaver

Here is the code I used:

declare global {
    interface Navigator {
        msSaveBlob?: (blob: any, defaultName?: string) => boolean
    }
}

if (navigator.msSaveBlob) {
    // use navigator.msSaveBlob
}
Sign up to request clarification or add additional context in comments.

3 Comments

Where do I declare that and how to import it?
Hopefully you'll be able to put it in the same file as you use msSaveBlob, that's what I was able to do. TypeScript is a little opinionated about where things like this can go. As I understand it, you have to use this in a file that either imports or exports something. If you don't, you'll get the compilation error "error TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."
Worked for me thanks. I just put it straight after the imports in the component.
4
  if ((window.navigator as any).msSaveBlob) {
        (window.navigator as any).msSaveBlob(blob, filename);
      }

1 Comment

This is the simplest, and achieves the same result => fooling the compiler.
3

I declared global namespace in my appmodule.ts file since its used in multiple files like this

 declare global{
 interface Navigator{
    msSaveBlob:(blob: Blob,fileName:string) => boolean
    }
 }

And calling file looks like this**//It was throwing build errors like you mentioned,

if (navigator.msSaveBlob) {
   // IE 10+
   navigator.msSaveBlob(blob, fileName);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.