Battle of the Blobs: Exploring Blob Source in Google Apps Script

I've been exploring clasp, a tool that allows developers to work with Google Apps Script using TypeScript.

Currently, I am working on a script that converts a Google Sheet into a PDF Blob and then uploads it to Google Drive.

While the code is executing without errors, I am facing some challenges in properly handling the types of Blob versus BlobSource to satisfy TypeScript.

Setting Up

To address this, I have defined some type abbreviations at the beginning of my file:

type Sheet = GoogleAppsScript.Spreadsheet.Sheet;
type SS = GoogleAppsScript.Spreadsheet.Spreadsheet;
type GBlob = GoogleAppsScript.Base.Blob;
type GBlobSource = GoogleAppsScript.Base.BlobSource;

In one of my functions, which has the following signature:

getPdfBlob(sheet: Sheet, pdfName: string): GBlob

I'm utilizing the function like this within my code:

var pdfBlob = getPdfBlob(mySheet, 'aPdfName');
var file = DriveApp.createFile(pdfBlob);

The Issue

However, my IDE is flagging an error indicating that DriveApp.createFile expects a parameter of type BlobSource instead of Blob.

Upon attempting to cast Blob into

BlobSource</code:</p>
<pre><code>var file = DriveApp.createFile(<GBlobSource>pdfBlob);

The feedback from my IDE raises concerns:

The conversion of type 'Blob' to type 'BlobSource' could potentially be incorrect due to insufficient overlap between the two. To proceed intentionally, consider converting the expression to 'unknown' first.

The property 'getBlob' is missing in type 'Blob' but is required in type 'BlobSource'.

Despite these warnings, the code still functions as intended. However, refining my type declarations is essential for maintaining TypeScript integrity.

After reviewing the documentation, it appears that Blob actually implements BlobSource. Hence, it's puzzling why there are obstacles when trying to "upcast" back to BlobSource. Could this issue possibly stem from inaccuracies in the TypeScript definitions?

I would highly appreciate any insights or guidance on addressing this matter correctly. Thank you!

Answer №1

To complete the task, all we have to do is integrate Class Blob from Interface BlobSource. Simply swap out the line with

export interface Blob extends BlobSource {

Recent Updates

DefinitelyTyped has been refreshed for this link to update

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to Setting Up Infinite Scroll with Next JS SSG

I recently built a markdown blog using the Next Js documentation and incorporated Typescript. When trying to retrieve a list of blog posts, I utilized getStaticProps as recommended in the documentation. However, my attempts with certain npm packages were u ...

Is there a way in Typescript to filter for the first instance of a unique object in an array of objects?

Having an array of JSON objects like this, the task is to iterate through it and retrieve the first occurrence of 'appname', such as 'app1' or 'app2', and store the entire object for each... myArray[ { ...

Exploring ways to conduct a thorough scan of object values, inclusive of nested arrays

My goal is to extract all values from an object. This object also includes arrays, and those arrays contain objects that in turn can have arrays. function iterate(obj) { Object.keys(obj).forEach(key => { console.log(`key: ${key}, value: ${o ...

Changing the function to operate asynchronously

How can I convert the following code into an asynchronous function? It is currently returning referralUrl as undefined: controller async createReferralUrls() { this.referralUrl = await this.referralService.generateReferralUrl(this.userData.referral ...

Tips for properly handling a property that receives its value from a callback function and waiting for it to be updated

Below is my TypeScript code: private getInfoSystem = () => { this.systemInfo = { cpuSpeed: 0 , totalRam: os.totalmem(), freeRam: os.freemem(), sysUpTime: os_utils.sysUptime(), loadAvgMinutes: { on ...

Using type aliases in Typescript to improve string interpolation

After working with Typescript for some time, I have delved into type aliases that come in the form: type Animal = "cat" | "dog"; let a1_end = "at"; let a1: Animal = `c${a1_end}` I initially thought that only the values "cat" ...

Angular2 RC definitions are not recognized by tsc

Currently, I am utilizing angular version 2.0.0-rc.1, however, I am encountering issues with the typescript compiler (Typescript version 1.8.10). Whenever I run tsc on my project, I am bombarded with numerous errors similar to this one: app/app.componen ...

Showing elapsed time similar to YouTube in an Angular 8 application

Currently, I am developing an Angular application to replicate certain features found on YouTube by utilizing data fetched from an API. This API provides video timestamps in a string format Each timestamp follows this structure : YYYY-MM-DDTHH:MM:SS For ...

Exploring the usage of array map parameters in rxjs 6 when combined with withLatestFrom

Prior to Rxjs 6, we were able to achieve the following: interface TypeA { payload: any; } source$.pipe( withLatestFrom(source2$, (source1: TypeA, source2: TypeB) => ({ payload: source1.payload, source2 }) ), ) In the resultSelector method ...

Error Alert: "Invariant Violation" detected in a TypeScript program utilizing React

When attempting to implement the react-collapse component in my TypeScript application along with a custom d.ts file, I encountered the following error: Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a ...

Error: Unable to inject UrlHandlingStrategy as no provider was found

I recently upgraded my application to Angular 14 and encountered a challenging error. Despite configuring RouterModule for Root and child with lazy loading, I am now facing a circular dependency issue related to the Router. I'm unsure how to further d ...

Bypass VueJs Typescript errors within the template section with Typescript

My VueJs App is functioning properly, but there is one thing that bothers me - a TypeScript error in my template block. Is there a way to handle this similar to how I would in my script block? <script setup lang="ts"> //@ignore-ts this li ...

Mastering the proper implementation of observables, async/await, and subscribing in Angular

I have a JSON file located at assets/constants/props.json. Inside this file, there is a key called someValue with the value of abc. The structure of the JSON file can be seen in the following image: https://i.stack.imgur.com/MBOP4.jpg I also have a serv ...

Disable the default animation

Is there a way to disable the default animation of the Select label in my code snippet below? export default function TicketProfile(props: any) { return ( <Container> <FormControl sx={{ ml: 1, mr: 1, minWidth: 220 }}> <Inp ...

Using TypeScript to validate the API response against specific types

I'm intrigued by the scenario where you expect a specific data type as a response from fetch / Axios / etc, but receive a different type instead. Is there a way to identify this discrepancy? interface HttpResponse<T> extends Response { parsed ...

Leveraging generics within TypeScript

I have developed a class in TypeScript that uses generics. export class ModelTransformer { static hostelTransformer: HostelTransformer; static fromAtoB(instance: T): U { if (instance instanceof HostelType) { return ModelTrans ...

The file located at 'node_modules/minimatch/dist/cjs/index' does not contain an exported element called 'IMinimatch'. Perhaps you intended to reference 'Minimatch' instead?

I encountered an error while using rimraf as a devDependency (v5.0.0) in my project. The error message I received was: node_modules/@types/glob/index.d.ts:29:42 - error TS2694: Namespace '".../node_modules/minimatch/dist/cjs/index"' has ...

The issue with the React Hook for window resize not updating remains unresolved

I have a React Hook designed to update the window size on resize, but it's not functioning correctly. Can someone please help explain why this is happening and provide guidance on how to utilize this hook in another component to create a Boolean value ...

What is the best way to keep track of choices made in 'mat-list-option' while using 'cdk-virtual-scroll-viewport'?

I have been working on implementing mat-list-option within cdk-virtual-scroll-viewport in an Angular 14 project. I came across a demo project in Angular 11 that helped me set up this implementation. In the Angular 11 demo, scrolling functions perfectly an ...

Using Typescript to collapse the Bootstrap navbar through programming

I've managed to make Bootstrap's navbar collapse successfully using the data-toggle and data-target attributes on each li element. If you're interested, here is a SO answer that explains a way to achieve this without modifying every single ...