How to export types in a TypeScript npm module - node.js

In TypeScript, say I want to have the user use my module's "internal" types so they can properly type their own variables when using my module - do I just export literally everything from my index.ts file to accomplish this?
// index.ts
export * from './file1' // uses types/interfaces defined in file1types
export * from './file2' // uses types/interfaces defined in file2types
export * from './types/file1types'
export * from './types/file2types'
Do .d.ts files help me accomplish this, or are they only for non-TS projects? Does tsconfig.json's option declaration: true help me accomplish this by generating a .d.ts for every TS file? Is this an alternative to exporting everything from a single index.ts file?
And if declaration: true does help me accomplish this, how would the user use all those generated .d.ts files within the build folder?
I would greatly appreciate some clarification as to how one typically exports types in TS projects. Thanks in advance.

For those who are like me, and have made sure declaration: true is set in your tsconfig.json, and that your build process correctly creates the corresponding .d.ts files to the appropriate directory pointed to by your package.json file, AND STILL somehow can't access the internal types of your module when testing on an external project -- try restarting the TS server in VSCode (assuming you're using VSCode)
So much time was wasted trying to figure this out, only to realize Typescript was functioning fine and I was being sabotaged by my IDE.

Without declaration files you can develop a package in TypeScript, compile it and expose it to other users as JavaScript code. Including them also allows TypeScript developers to use the package with any types you defined in it. They can get more type information whilst working with your library, such as required arguments types, function return types etc, as well as warnings from their IDE/Intellisense when there are conflicts.
The declaration: true in the file tsconfig.json instructs the TypeScript compiler to output declaration files (.d.ts). Often they are bundled in a single file e.g. index.d.ts and then a "types": path/to/index.d.ts field is added to the library's package.json file to inform TypeScript where to look for the types (when a user imports the package).

Related

VS Code Intellisense for auto exported global variables

Sails exports a set og global variables, such as:
_ (lodash)
sails (framework related)
ModelOne, ModelTwo, ModelThree, ... (the sails models we define)
Creating a jsconfig.json targeting es5 doesn't help since the variables aren't explicitly declared.
I have this variables declared on eslintrc.globals, but that just tells the linter they exist.
Ideally I'd like to have intellisense for this variables across my project.
Is there any way I can declare this global variable types in VS Code?
At the time of this writing, looking at the npm page for sails.js, they don't provide type declaration files, and don't have community contributed type declaration files in the Definitely Typed project.
Your options are:
Contribute type declaration files to the Definitely Typed project for sails.js (see their contributing instructions), and then install your contributed types package (like npm install -D '#types/sailjs' (or whatever it gets called))
Create your own type declarations NPM package (outside of the Definitely Typed project) and use that. In that case, see the TypeScript guide on publishing declaration files.
Create a type declaration file (myfDeclarationFile.d.ts or something of your choice) and define those types there. Put the file anywhere where it will be picked up as part of your project based on your tsconfig.json/jsoconfig.json file.
Note that in this case, you might need to make sure the name of the .d.ts file you create might need to not have the same name as other .ts files in the same directory (see https://github.com/microsoft/TypeScript/issues/51128).
In your particular case, since these are type declarations for globals, see TypeScript's guide for declaring types for global libraries. For guides for other types of libraries, see the guide index page.

Should I write TypeScript definitions for my TypeScript module?

I am the process of writing my first TypeScript-based NPM module. When I am done, it will be exported through "main" in package.json, and this field will point at the compiled, plain javascript.
So when I require this module in another TypeScript module, IntelliSense and type checking will not work for my module, right?
So one solution would be to add a definition file. But definition files are for JS libs, right? It shouldn't be necessary to write a definition file for a TS project, right?
So... how am I going to export my definitions along with my project?
It seems I just need to add "declaration": true to my tsconfig.json. Pretty simple.

TypeScript ES6 namespaces

I have a Node.js project I recently converted to TypeScript from ECMAScript 6-compatible JavaScript. I am still not entirely familiar with how TypeScript and ES6 interact, especially in regards to namespaces and types.
I have a subfolder in my project called sql which, as it sounds, exports a number of functions to interact with the project's MySQL database. I would like to organize my DB model types in a Sql.Models namespace, so they can be referenced e.g. Sql.Models.User. I would like my models to be declared in one or more .d.ts files inside the sql folder, but I can't figure out how to properly organize this so that these types can be referenced elsewhere. I obviously cannot require or import a .d.ts file; that's not a valid TypeScript operation. How can I use the type Sql.Models.User declared in a .d.ts file in another ES6-compatible TypeScript module?
How can I use the type Sql.Models.User declared in a .d.ts file in another ES6-compatible TypeScript module?
The following very simple setup works.
root
sql
models.d.ts
index.ts
tsconfig.json
The model.d.ts file declares a namespace and a type. As the image demonstrates, the index.ts file can alias that namespace and/or access it directly.
The above is using TypeScript version 2.2.1.
I solved this in a less-than-pretty fashion by using "aliased internal imports" which sound strange but really aren't. I export an alias to an internal symbol, which just happens to be a symbol imported from another file.
I would have preferred something like how C# works, where I can define the namespace in two files and somehow alias one from another so that only one file needs to be referenced, but this doesn't seem possible with ECMAScript 6-compatible TypeScript.

how are #types, typescript and webpack related

To use an exported type in .ts file one has to add import it
import {jQuery} from 'jQuery'
Now when I use this I do not get intellisense, I still need to do npm install #types\jQuery to get that.
So without #types, above statement just infers that during typescript bundling include this file.
Now if I install #types then without adding any other code, I do start getting intellisense.
So is it like above statement is dual purpose.
During bundling using typescript/webpack, it tells to bundle these files as dependency and during compilation, it tells to include .d.ts rather than actual code file?
Why this question: I am trying to move angular1 to typescript and I can use angular.whatever in .ts file even without importing it? Not getting why this is happening. It should give me error asking me to import angular
Not sure I get your question 100% but I can try to explain a bit. The javascript runtime won't have a static check, it is just during the compilation time. If you tell typescript that your variable/function/etc. is of type 'any' then it will just allow you to do anything with it. Eventually the generated code is the same, whether it is checked or not. If you don't have corresponding variable during runtime, you will get an error. Typings are used to just "teach" ts compiler about the actual types of variable for static compilation.
So during compilation no .d.ts is included anywhere, this is just for static type check.
As to why you can access angular, I suppose it is because of d.ts contains the definition and by using #types/angular you let ts compiler know about it.
Check here. The .d.ts files includes global variable angular, that's why you can use it without importing I think.
P.S. Not sure 100%, but seems like it is this line:
declare var angular: angular.IAngularStatic;
You can try deleting this line and see if you get your error :)

How do I import a library into node without a Typescript/TSD definition?

I'm trying to use a session helper called connect-session-knex which is obscure enough that it does not have a published typescript definition. So when I try to compile my typescript node project, I get the error,
error TS2307 Cannot find module 'connect-session-knex'
Is there a way to ignore TS for this module only? How do I import it without the TSD? I know knex has a tsd, but the wrapper does not. I'm asking this from a generic standpoint of what to do with libraries without type definitions.
For anyone looking: Compiling typescript when it does not have tsd. Missing tsd. Without tsd.
error TS2307 Cannot find module 'connect-session-knex'
Is there a way to ignore TS for this module only? How do I import it without the TSD?
Use var/require instead of import/require. i.e.
var csk = require('connect-session-knex');
Note you should have node.d.ts included for require to be declared.
Also : https://basarat.gitbooks.io/typescript/content/docs/node/nodejs.html
Another suggestion is to start you own .d.ts file as an empty definition file and export the module. Then if you want to get intellisense on the module you can add definitions to it.
e.g. connect-session-knex.d.ts:
// declare module
declare module "connect-session-knex" {
}

Resources