I'm trying to use Jimp with TypeScript in a following manner:
import * as Jimp from "jimp";
let image = new Jimp(256, 256, function (err, image) {
});
It produces the following errors:
severity: 'Error'
message: 'Only a void function can be called with the 'new' keyword.'
at: '2,13'
source: 'ts'
code: '2350'
severity: 'Error'
message: ''new' expression, whose target lacks a construct signature, implicitly has an 'any' type.'
at: '2,13'
source: 'ts'
code: '7009'
However, when I ignore the TypeScript compile-time errors and debug the result, it works just as expected, i.e. the image is created successfully. So it looks like we have a problem with jimp.d.ts. In fact, it describes the corresponding constructor not as a constructor, but as a regular function.
My main hypothesis is that d.ts file was prepared for an older version of TypeScript and uses different ways to describe Jimp class (a function with a prototype). However, I'm new to TypeScript, so I may miss something.
I've tried playing around with module augmentation (using this technique for the first time, actually), but got a following error: Cannot augment module 'jimp' because it resolves to a non-module entity.
The project details are as follows.
tsconfig.json:{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"strict": true,
"outDir": "dist",
"lib": [
"es5",
"es2015.iterable"
]
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
Don't use "new", use as described.
import * as Jimp from "jimp";
Jimp.read(buffer).then((image) => {
image.resize(42, 42).write("/path/for/image.jpg");
})
.catch((err) => {
debug("Profile picture resize throw an error!", err);
});
or you can use with await/async
import * as Jimp from "jimp";
const image= await Jimp.read(buffer);
image.resize(42, 42).write("/path/for/image.jpg");
@brendtumi, you've just shown how to use static methods (Jimp.read(buffer)) to read an existing image.
But I need to create an image from scratch, and there are several overloaded constructors for that in jimp.d.ts (which are not actually constructors, as they don't compile with new), and there's an explicit instruction to use new Jimp(...) for this case in the readme. Does it mean that the readme is outdated?
It's possible to outright circumvent or ignore the TypeScript compiler warnings either by inserting // @ts-ignore in the line before or by calling the "constructor" as new (Jimp as any).
Both aren't pretty, but they at least get the job done.
@jagoe, yes, using new (Jimp as any)(...) does work. But we still expect the declaration file to provide the correct method signature to use it, not to fight an incorrect one.
Any ideas (and pull requests) how to refactor the declaration file to declare using new Jimp(...) correctly?
You're right, that's nothing but a quick fix.
I looked into it and created a pull request (#430) that should fix the issue.
Most helpful comment
@brendtumi, you've just shown how to use static methods (
Jimp.read(buffer)) to read an existing image.But I need to create an image from scratch, and there are several overloaded constructors for that in
jimp.d.ts(which are not actually constructors, as they don't compile withnew), and there's an explicit instruction to usenew Jimp(...)for this case in the readme. Does it mean that the readme is outdated?