Firebase CLI Typescript error TS2345 thrown on code that previously compiled - node.js

Good evening,
I recently updated the firebase CLI for cloud functions, and when I try to deploy my old index.ts file, I get a TS2345 error:
src/index.ts:364:13 - error TS2345: Argument of type '(req: Request, res: Response<any>) => Response<any> | Promise<void | Response<any>>' is not assignable to parameter of type '(req: Request, resp: Response<any>) => void | Promise<void>'.
Type 'Response<any> | Promise<void | Response<any>>' is not assignable to type 'void | Promise<void>'.
Type 'Response<any>' is not assignable to type 'void | Promise<void>'.
Type 'Response<any>' is not assignable to type 'Promise<void>'.
364 .onRequest((req, res) => {
my function that is trowing this error looks like this:
exports.https_rec = functions.https
.onRequest((req, res) => {
if (req.method === 'PUT') {
console.log("HTTPS Attempted Connection");
return res.status(403).send('Forbidden!');
}
else{
//Do Stuff
return res.status(200).send("ok");
}
});
Everything was working and uploading fine, but after I updated the CLI, I now get this TS2345 error on code that previously compiled. I found a sample function from Firebase (from a few years ago) where the structure is the same as how I have presented it, which tells me something must have changed recently.
https://github.com/firebase/functions-samples/blob/master/quickstarts/time-server/functions/index.js#L39
Other specs:
Windows 10
NPM Version 14.5.0
Firebase-tools version 8.6.0
Any thoughts or recommendations? Is there an easy code change to make, or should I revert back to an older version of the CLI or tslint?
Thank you for your time in advance!

They changed the return type of https triggers recently.
You shouldn't "return" anything as a response.
Just delete return and you're good to go.
Example:
exports.https_rec = functions.https
.onRequest((req, res) => {
if (req.method === 'PUT') {
console.log("HTTPS Attempted Connection");
return res.status(403).send('Forbidden!');
}
else{
//Do Stuff
res.status(200).send("ok");
}
});

Related

RxJS Http Server with typescript compile errors

I'm pretty newbie with rxjs, can you please tell what's wrong with below?
interface IHTTP {
req: IncomingMessage;
res: ServerResponse;
handler?: Promise<any>;
}
server = http.createServer();
let request$: Observable<any>;
request$ = fromEvent(server, 'request').pipe(
map(([req, res]: [IncomingMessage, ServerResponse]): IHTTP => {
return { req, res } as IHTTP;
}
)
);
Compile error:
TS2345: Argument of type 'OperatorFunction<[IncomingMessage, ServerResponse], IHTTP>' is not assignable to parameter of type 'OperatorFunction<unknown, IHTTP>'.   Type 'unknown' is not assignable to type '[IncomingMessage, ServerResponse]'.
I found the problem I had to define fromEvent's first argument as:
server as FromEventTarget<[http.IncomingMessage, http.ServerResponse]>
Otherwise Typescript thinks it's FromEventTarget<unknown>

Electron issue after updating electron and typescript

I have a small electron project which I've just updated (Electron, typescript etc)...
This is the code that's breaking:
dialog.showOpenDialog({}, (files) => {
if(files && files.length > 0) {
fs.readFile(files[0], 'utf8', (err, res) => {
if (!err) {
editor.setModel(monaco.editor.createModel(res, 'javascript'));
}
})
}
})
It doesn't like the {} after dialog.showOpenDialog(
The error I'm getting is:
Argument of type '{}' is not assignable to parameter of type 'BrowserWindow'.
How can I fix this?
The showOpenDialog is used differently, probably you updated from a quite old electron version and they changed it. Now it takes an optional browserWindow and an options object and returns a promise (shown with the async/await syntax):
const {canceled, files, bookmarks} = await dialog.showOpenDialog({});
Reference: https://www.electronjs.org/docs/api/dialog#dialogshowopendialogbrowserwindow-options

TypeScript - Type undefined is not assignable to type ICustomType

I'm quite new to TypeScript and trying to understand what is the best way to approach such situation in my code.
I have array of objects that have a custom type in my system and I use Array.find method to get one of them. However I receive a compile error saying Type 'undefined' is not assignable to type IConfig.
Here's the code example -
const config: IConfig = CONFIGS.find(({ code }) => code === 'default');
// Type 'undefined' is not assignable to type IConfig
I tried to add undefined as possible type but then I get error on the next line which uses this object Object is possibly 'undefined', e.g. -
const config: IConfig | undefined = CONFIGS.find(({ code }) => code === 'default');
// Object is possibly 'undefined'
if (config.foo) {
return 'bar';
}
What is the best way to approach such type issues?
.find will return undefined if nothing in the array passes the callback test. If you're sure that default code exists in the array, then use the non-null assertion operator:
const config: IConfig = CONFIGS.find(({ code }) => code === 'default')!;
// ^
(If you weren't sure if it exists in the array, the warning you see is there to prompt you to explicitly test for if the item exists before trying to access a property on it, otherwise you'll sometimes get a runtime error:
const config: IConfig = CONFIGS.find(({ code }) => code === 'default');
if (!config) {
return 'No match found';
}
if (config.foo) {
return 'bar';
}
)

How to fix Typescript compilation error ts2345 "Type 'Response' is missing ... from type 'Response': redirected, trailer, formData!"

I am trying to make a request using node-fetch in my typescript project and I do not understand how to fix the compilation error or what it actually tries to tell me.
I've updated all packages (including the global typescript package) to the latest versions.
I've created a gist that isolates the error: https://gist.github.com/HerrZatacke/ae90f608e042864b6e00e9c73a950602
This (very short) script is able to reproduce the compilation error:
import fetch from 'node-fetch';
const toJson = (response: Response):PromiseLike<object> => (
response.json()
);
const makeSomeRequest = (): Promise<object> => {
return fetch('https://some-api.com/')
.then(toJson)
};
makeSomeRequest();
The installed versions used are
#types/node-fetch 2.3.7
node-fetch2.6.0
typescript 3.5.2
the actual error is
example.ts:9:11 - error TS2345: Argument of type '(response: Response) => PromiseLike<object>' is not assignable to parameter of type '(value: Response) => object | PromiseLike<object>'.
Types of parameters 'response' and 'value' are incompatible.
Type 'Response' is missing the following properties from type 'Response': redirected, trailer, formData
With the help/hints of the two commenters above (thanks a lot), I managed to find the reason and a solution for that error:
Typescript initially tries to "guess" which types you are using.
The following line states I want to use the type response, which is an interface of the native Fetch API
const toJson = (response: Response): Promise<object> => {
the type definition for it can be found in lib.dom.d.ts
node-fetch instead is implementing it's own Response type from #types\node-fetch\index.d.ts
So, if the correct response type is being imported first, the typescript compiler runs without the error.
Which means, instead of just importing node-fetch, you also have to import it's definition of Response:
import fetch, { Response } from 'node-fetch';

Typescript error TS2345 Error: TS2345:Argument of type 'Buffer' is not assignable to parameter of type 'string'

new to Typescript. I am reading some data from RabbitMQ channel and am converting it to JSON object. In this line I get the error
let communicationInformation = JSON.parse(newCommunication.content);
TS2345:Argument of type 'Buffer' is not assignable to parameter of type 'string'.
Do I need to cast the data? I am using Typescript 2.4.1
Amqplib.connect(amqpLibUrl, (err, connection) => {
if (!err) {
connection.createChannel((err, channel) => {
channel.consume('QueueName', newCommunication => {
if (newCommunication != null) {
let communicationInformation = JSON.parse(newCommunication.content);
// Code
}
})
})
}
});
I think the error is thrown on the input parameter of JSON.parse. Try to first call toString on it then pass to the function.
let communicationInformation = JSON.parse(newCommunication.content.toString());
I am not sure what is newCommunication.content. In my case it is a file and I had to specify encoding for fs.readFileSync:
const level = JSON.parse(fs.readFileSync('./path/to/file.json', 'utf-8'));
Next Error was error TS2531: Object is possibly 'null'.
You have to disable strictNullChecks in your compiler

Resources