Fixing common TS typings

Issue 1

This is due to the fact that the typings do not have the module defined. @pklaschka mentioned in a response that the docs define this as a global class. That appears to not be the case: according to Adobe devs on these forums, OS is indeed a module. Both documentation and typings updates will be required.

Issue 2

There are two errors here. The first error says that the response you get from the getFileForOpening() API call will return either a File or an Array of Files. Those objects will have different APIs and it is unsafe to “assume” one or the other. Your assumption is made explicity by your JSDoc-style type annotation. The second problem is that you are, as suggested by @pklaschka, referring to the Web DOM File definition. There are two ways around both of these issues.

Option 1

Import the UXP File type under a different name and use it. See:

const UXPFile = require('uxp').storage.File;

// ...

/**
 * @type {UXPFile|UXPFile[]}
 */
let selectedFile = await fileSystem.getFileForOpening();

Option 2

Make use of TypeScript’s “import types”. See:

/**
 * @type {import('uxp').storage.File|import('uxp').storage.File[]}
 */
let selectedFile = await fileSystem.getFileForOpening();

Both options will clear your errors and allow you to make use of the functions. Option 2 may be more verbose but it has the benefit of not actually importing the UXP File type into your module’s scope.

Issue 3

Assuming that you corrected the issues above, your selectedFile should at this point be of type UXPFile (considering Option 1 above). If these are in the same script, then you would want to take Option 1 because it allows you to narrow the type of your selectedFile to what you want. Specifically:

const UXPFile = require('uxp').storage.File;

// ...

if (selectedFile instanceof UXPFile)
{
    selectedFile.nativePath; // No more problems!
}

Issue 4

This is due to the fact that your file instance is typed as Entry, the superclass of both the UXP File and UXP Folder classes. You don’t actually know what type you have! You could have a Folder that has the same name as your filename parameter!

To both clear this error and program more safely, do the following:

const UXPFile = require('uxp').storage.File;
const UXPFolder = require('uxp').storage.Folder;

// ...

const entries = await pluginDataFolder.getEntries();
const files = await entries.filter(entry => entry.name.indexOf(filename) >= 0);
var file = files[0];
if (file instanceof UXPFile)
{
    let data = await file.read();
}
else if (file instanceof UXPFolder)
{
    // something else?
}

You may also wish to change the name of some of your variables to better reflect what you’re actually getting (e.g. filesfilesOrFolders).

Issue 5

You are being told that your newFile type is either a UXP Folder or a UXP File. If both of the types had a write method with the same signature (parameter number and type and return type) defined then there wouldn’t be a problem. However, the UXP Folder class doesn’t have such a method. As such, you need to be clear of your intentions:

const UXPFile = require('uxp').storage.File;
const UXPFolder = require('uxp').storage.Folder;

// ...

if (newFile instanceof UXPFile)
{
    newFile.write(data);
}

Issue 6

You haven’t imported the UXP Folder type into your scope. You can do this with the same two options suggested in the File version of this above.

However, when you do so, you will get a different error. The getEntry method does not return a Folder instance! It returns an Entry instance. That can be either a Folder or a File. You will therefore need to do something like this:

const UXPFile = require('uxp').storage.File;
const UXPFolder = require('uxp').storage.Folder;

// ...

// [NOTE] The JSDoc type was removed. The language service
//  should be able to figure out the type automatically. If you want
//  to add the type, it should be something equal to:
//    @type {import('uxp').storage.Entry};
const entry = await pluginFolder.getEntry(filePath);

if (entry instanceof UXPFile)
{
    // Do file stuff.
}
else if (entry instanceof UXPFolder)
{
    // Do folder stuff.
}

I hope that someone finds this information helpful!

2 Likes