Using TypeScript types from JS - javascript

I've enabled checkJS and allowJS in Typescript and created a simple fooInterface.d.ts file:
declare interface FooInterface {
x();
}
I'm trying to typecheck a JS file against this interface:
/**
* #implements {FooInterface}
*/
class Bar {
y() {}
}
However I can't get it to throw an error upon running tsc.
Also tried simply writing declare class, didn't work either.
How can I reuse types from .d.ts files in JSDoc+JS?

Supporting the JSDoc #implements tag has been requested in TypeScript and is tracked by https://github.com/Microsoft/TypeScript/issues/17498
The #extends tag will be supported in the next release of TypeScript (2.7) and is already available in the nightly builds (typescript#next) which, I might add, are remarkably stable.
You can get the nightly build with your package manager of choice. For example
using npm
$ npm install typescript#next
using jspm
$ jspm install typescript#next
using yarn
$ yarn add typescript#next

Related

structuredClone() not available in TypeScript

I'm running node.js v17.2.0 and TypeScript v4.5.4. I'm trying to use structuredClone() on a Map, and it doesn't seem to be working. ES2021 is targeted in tsconfig.json, and included in lib. Is this function just plain not available in TypeScript? Is there something else I need to include to get it?
#types/node is also installed, and I've made sure that it works in node.js environment.
structuredClone is now present in #types/node v17.0.29:
Run the following command to have access to it:
npm i --save-dev #types/node#17.0.29
structuredClone will be available in lib.dom of TypeScript v4.7 (as of 2022-05-19 it is currently in beta, but will be out soon). You can see where structuredClone was added to TypeScript here.
If you need to add it to your project temporarily until you can upgrade TypeScript, you can do that by putting the following definitions from the commit linked above into a structuredClone.d.ts file in your project (the base name doesn't matter, but the .d.ts does):
interface WindowOrWorkerGlobalScope {
structuredClone(value: any, options?: StructuredSerializeOptions): any;
}
declare function structuredClone( value: any, options?: StructuredSerializeOptions): any;
(StructuredSerializeOptions is already defined by lib.dom.d.ts for postMessage, so we don't need to add it.)
Then just remove that file when you've upgraded later.
It was an ackowledged bug in Jest.
Jest supports structuredClone since v28.0.0-alpha.8 which is just above 28.0.0
https://github.com/facebook/jest/issues/12628
jest-preset-angular is nearly at the stage of supporting that jest version.
According to the below issue 13.0.0-next-1 does.
https://github.com/thymikee/jest-preset-angular/issues/1774

Flow: Throws error Cannot resolve module "react-redux" even tho it's installed

Even tho module is installed and it exists, Flow cannot resolve it and throws error.
See below:
1) Inside bash I ran flow and it throws error that module is not found
user#pc:~/code/project$ flow
Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ src/functionalities/Growth/index.js:3:25
Cannot resolve module react-redux.
1│ // #flow
2│ import React from "react"
3│ import { connect } from "react-redux"
4│
5│ type Props = {
6│ children: Function
Found 1 error
2) Below command checks whether directory exists and it does
user#pc:~/code/project$ ls node_modules | grep react-redux
react-redux
I tried to remove and reinstall both node_modules directory and yarn.lock file.
Versions should be matching:
flow version
Flow, a static type checker for JavaScript, version 0.77.0
.flowconfig:
[version]
0.77.0
This is very likely bug with Flow, I also submitted issue.
How to fix it
You have two options:
stub the dependency by hand
bring in flow-typed to find the dependency type
file/stub it for you
I use option 2 but it is nice to know what is happening underneath
Option 1
In .flowconfig, add a directory under [libs],
...
[libs]
/type-def-libs
...
Now, create that directory at your project root and a file /type-def-libs/react-redux which contains,
declare module 'react-redux' {
declare module.exports: any;
}
Option 2
install flow-typed, if using yarn yarn add -D flow-typed
I prefer to install every locally to the project when possible
run yarn flow-typed install
this will install any type definition files for modules that it finds AND it will stub any modules it doesn't find, which is similar to what we did in option 1
Why is this error happening
Flow is looking for the type definition for the module you are importing. So while the module does exist in /node_modules that module doesn't have a type definition file checked into its code.
I had the same issue as you.
I resolved it by using flow-typed
I did the following:
Install flow-typed globally. example: $ npm install -g flow-typed
Then inside your project root folder, run $ flow-typed install react-redux#5.0.x
• Searching for 1 libdefs...
• flow-typed cache not found, fetching from GitHub...
• Installing 1 libDefs...
• react-redux_v5.x.x.js
└> ./flow-typed/npm/react-redux_v5.x.x.js
react-redux
You should see this if the install was successful.
Then try running flow again $ npm run flow in your project. The error with react-redux will no longer be there.
Alternative solution (for some cases)
Check your .flowconfig and remove <PROJECT_ROOT>/node_modules/.* under the field [ignore] (in case you have it there).
UPDATE 1 (by arka):
Or you can add !<PROJECT_ROOT>/node_modules/react-redux/.* after <PROJECT_ROOT>/node_modules/.*. This will ignore all the modules except for react-redux.
Thanks to #meloseven who solved it here.
I checked my package.json file and noticed react-redux was missing. I manually added it to the dependencies "react-redux": "x.x.x" and ran npm install thereafter. Note that the version number should be compatible with the other modules.
Please ensure that you provide the path under 'ignore' in .flowconfig, like this:
[ignore]
.*/node_modules/react-native/Libraries/.*
and not like this:
.*/node_modules/react-native/Libraries/Components
.*/node_modules/react-native/Libraries/Core
....

how can I get warnings when importing modules that don't exist

Im using EsLint with VsCode.
How can I have an error appear when trying to import a module that doesn't exist ?
for example
import foo from './this-path-doesnt-exist'
Should underline in red.
Does this require an eslint plugin ?
If you are using eslint as your linter, you can use eslint-plugin-import .
This plugin intends to support linting of ES2015+ (ES6+) import/export
syntax, and prevent issues with misspelling of file paths and import
names
In addition to the eslint plugin suggested, you can enable semantic checking for a JS file in VS Code by adding // #ts-check at the top of the file:
// #ts-check
import foo from './this-path-doesnt-exist'
This will enable a number of other checks in the file as well, including type checking, so it may not be appropriate for every code base but it can help catch many common programming mistakes.
More info about ts-check
If you are already not using linter follow below steps:
npm install eslint --save-dev
npm install eslint-plugin-import --save-dev
then you need to configure
extends:
eslint:recommended
plugin:import/errors
plugin:import/warnings
into your .eslintrc.(yml|json|js) file manually.
If you are already using linter. Skip step one to install eslint.
And dont forget install extention ESLint, i spent tonn of time on config but problem was in extention.

Is there a correct way to use a JavaScript module in a TypeScript project?

I really hope this isn't an opinion question, and I don't think it is...
Is there a correct way to include a JS module in a TS project? If I don't do one of the 2 steps below, my IDE (linter, wahtever) gives me TS2307: Cannot find module when I use the line import * as myPackage from 'myPackage'.
The steps I use are
npm i thePackage --save
typings i -g thePackage --save // assuming it has a typings
If the module doesn't have a typings, all you do is
declare let myPackage:any
Is that all you have to do in order to use an external package in a TS project? Or am I missing a vital step?
I know I could create a .d.ts file, but for now, I'd like to get the hang of TS without spending all my time writing those files.
I've also been reading about DefinitelyTyped and #types/myPackage, but I don't know much about it...
If the package has declaration files
In TypeScript 2.0+, for a package the-package
npm install --save #types/the-package
If the package doesn't have declaration files
If the package doesn't have declaration files for it, create a file named externals.d.ts with the following:
// This file should contain no top-level imports or exports.
declare module "the-package";
Note: If there's more than one thing you can import from the-package, you can use a wildcard as well:
declare module "the-package/*";
At this point, you can do basically whatever you want with the package when you import it - it comes in as any.
Strongly typing the package
If you want to add some type safety, we'll start defining the module in its own file in a folder called externals.
So we'll write out ./externals/the-package/index.d.ts.
export function foo(): void;
export function bar(x: string): number;
And now add the following to your tsconfig.json's compiler options.
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"*": ["externals/*"]
}
}
}
Now any modules should be looked up in externals first before being looked up in #types & node_modules.
Note: This assumes externals is in the same directory as tsconfig.json. Adjust appropriately.
Once your module is fully written out, you can send a PR for this package to DefinitelyTyped if you'd like to help others out.

"JQuery Interface file" for Flow (Static Type Checker for JavaScript from Facebook)?

In Nov. 2014, 3 months ago, Facebook open-sourced a new command line tool, a static type checker called "Flow". Now I want to run it on a few of my older, existing javascript files. These contain references to the jQuery library.
My JS files were not written with static type-checking in mind.
however, after including /* #flow */ at the top of the file, when I run flow with this Command:
flow myfile.js
Result:
/var/www/myfilejs:70:12,17: identifier jQuery
Unknown global name
Found 1 error
As I understand it, the way to include jQuery into Flow's type checking process is to create an "interface file".
Has anyone done this yet for the jQuery library? (I use jQuery 1.9)
This is my interface file I like to call jQuery.js in a folder I call "flow_lib". This folder can be anywhere.
This is the code the jQuery.js contains for the interface declaration :
declare module "jQuery" {
declare function $(obj: any): any;
}
var $ = require('$').$;
In your .flowconfig, include the folder like this :
[ignore]
[include]
[libs]
<path-to-folder>/flow_lib
[options]
Note : This method does not check for actual jQuery specifications. It's just a quick fix to get rid of the flow warnings and errors related to $ in your code. If you want to be more specific, use something like : https://github.com/solnetdigital/flow-interfaces-jquery/blob/master/interfaces/jquery.js
If you want an actual jQuery flow interface definition, you can look at the one provided in https://github.com/marudor/flowInterfaces.
Install it with:
npm install --save-dev iflow-jquery
or
yarn add --dev iflow-jquery
And then add the following to your .flowconfig file:
[libs]
node_modules/iflow-jquery/index.js.flow
After that, flow will infer the types of the parameters you provide to jquery functions, and will warn you if you are passing the incorrect types.

Categories