You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In a project using JSDoc, you will often want to avoid the any type. A common place where you find this is when you require('tape') or any other dependency that does not come with either an index.d.ts or (valid) JSDoc annotations internally.
Some libraries ship with type defintions, for example aws-sdk so they do not need to be managed by you.
There are two ways of managing the type definitions of your dependencies. You can either vendor them or you can manage them by using npm
Installing type definitions with npm
You can install the types of library by using npm install @types/tape and it will fetch the types from DefinitelyTyped
There are pros & cons to this approach.
Pros
Great for getting started, install types with one command
Great for community projects, for example npm install @types/node. The node types are not perfect but they are still non-trivial and simpler then vendoring them.
Cons
The quality of the types is questionable since they are not written by the module author
The type definitions are not specific to your personal jsconfig.json or version of TypeScript, they may not be compatible.
You cannot lint or type check these definitions based on eslint / tsc + jsconfig.json
Contributing changes upstream is chunky & slow.
The definitions are not vendored so you cannot easily code review them in a pull request.
Vendoring type definitions.
Alternatively to installing type definitions from npm you can actually include type definitions for dependencies in your own project. I personally use a types or _types directory.
You can tell typescript in a jsconfig.json to use these types at type check time
You specify that all unkown modules * comes from _types. Unfortunately any modules that are "scoped" and have a / in the name have to be rewritten in the x__y style, DefinitelyTyped has a similar limitation.
The _types directory contains one directory per third party dependency and inside there's an index.d.ts; this layout is incredibly similar to the layout of for example @types/tape from npm. The best way to get started with vendoring is to install a type defintion from @types/xyz and then copy it into _types and then delete that @types/xyz dependency.
Once a type definition is vendored you can include in your jsconfig.json
"include": [
...
"_types/**/*.d.ts"
]
This will make tsc type check the third party dependencies and apply your typescript configuration rules against your dependencies. Secondly, once included, eslint will also lint your third party dependency configuration.
I've found this tooling integration to especially helpful in enforcing the no-explicit-any rule, which annoyingly get's "cheated" by the type definitions in @types/node for some nodejs builtins.
Pros
The same rules that your app code has for tsc / eslint get applied to your dependencies. Your dependencies are no longer "less strict" then your app code in terms of type safety.
You can review and more importantly improve the accuracy of your third party dependencies easily. ( I've made some patches to basically all third party deps ).
The quality of the third party dependency types is fully under your own control, you don't have to deal with making patches to definitelytyped or not being able to make types more strict because it would break back compat.
Cons
There is more configuration in jsconfig.json
You have to do more work, it's not as trivial as npm install @types/node.
You will be tempted to reduce duplication by creating your own @raynos/types package and putting them all in there. Don't do that, avoid this temptation.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
In a project using JSDoc, you will often want to avoid the
any
type. A common place where you find this is when yourequire('tape')
or any other dependency that does not come with either anindex.d.ts
or (valid) JSDoc annotations internally.Some libraries ship with type defintions, for example
aws-sdk
so they do not need to be managed by you.There are two ways of managing the type definitions of your dependencies. You can either vendor them or you can manage them by using
npm
Installing type definitions with npm
You can install the types of library by using
npm install @types/tape
and it will fetch the types from DefinitelyTypedThere are pros & cons to this approach.
Pros
npm install @types/node
. The node types are not perfect but they are still non-trivial and simpler then vendoring them.Cons
jsconfig.json
or version of TypeScript, they may not be compatible.eslint
/tsc
+jsconfig.json
Vendoring type definitions.
Alternatively to installing type definitions from
npm
you can actually include type definitions for dependencies in your own project. I personally use atypes
or_types
directory.You can tell typescript in a
jsconfig.json
to use these types at type check timeYou specify that all unkown modules
*
comes from_types
. Unfortunately any modules that are "scoped" and have a/
in the name have to be rewritten in thex__y
style,DefinitelyTyped
has a similar limitation.The
_types
directory contains one directory per third party dependency and inside there's anindex.d.ts
; this layout is incredibly similar to the layout of for example@types/tape
from npm. The best way to get started with vendoring is to install a type defintion from@types/xyz
and then copy it into_types
and then delete that@types/xyz
dependency.Once a type definition is vendored you can include in your
jsconfig.json
This will make
tsc
type check the third party dependencies and apply your typescript configuration rules against your dependencies. Secondly, once included,eslint
will also lint your third party dependency configuration.I've found this tooling integration to especially helpful in enforcing the
no-explicit-any
rule, which annoyingly get's "cheated" by the type definitions in@types/node
for some nodejs builtins.Pros
tsc
/eslint
get applied to your dependencies. Your dependencies are no longer "less strict" then your app code in terms of type safety.Cons
jsconfig.json
npm install @types/node
.@raynos/types
package and putting them all in there. Don't do that, avoid this temptation.Beta Was this translation helpful? Give feedback.
All reactions