If I have a TypeScript module saved as my-function.ts as follows :
export function myFunction (param: number): number { return param }
This will be compiled to JavaScript in whichever way and loose its type definitions. I am then able to create a index.d.ts file which declare this module's definitions, but this seems a bit tedious to redefine/redeclare the definitions.
Are there ways to generate the type definitions automatically from the my-function.ts file to a index.d.ts file?
If you compile with the --declaration
flag, TypeScript will automatically generate .d.ts
files for you.
This mode will require that you certain types are visible so that they can be described in your .d.ts
files.
My tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"declaration": true,
"outDir": "./tsOutputs"
},
"include": [
"lib/**/*.ts",
"index.ts"
],
"exclude": [
"test/**/*.ts"
]
}
Note: In order to be able to cast & create instances of objects, you need to have two different exports per each entity. Once as type and another as const .
Here's my index.ts:
import {HttpClient as HC} from "./lib/http/http-client";
import {HttpRequest as HReq, HttpResponse as HRes} from "./lib/http/contracts";
export namespace MyJsInfra
{
export type HttpClient = HC;
export namespace Entities{
export type HttpRequest = HReq;
export const HttpRequest = HReq;
export type HttpResponse = HRes;
export const HttpResponse = HRes;
}
}`
You can read more info on the reasoning behind this dual declaration in here: https://github.com/Microsoft/TypeScript/issues/10058#issuecomment-236458961
After all of the following, when we'll run build we should have the corresponding "*.d.ts" files per each type. Now we have to handle the package.json of the infra, in order to pack all the items.
Inside the package.json make sure to set the types , main to point to the generated index.d.ts & index.js files. In addition, you have to make sure that the "*.d.ts" files are being packaged as part of infra. In my case, I've specified the following pattern in the files property: "tsOutputs/**/*.d.ts"
Here's my package.json:
{
"name": "my-js-infra",
"version": "1.0.0",
"description": "Infrastructure code.",
"scripts": {
"build":"./node_modules/.bin/tsc -p .",
"prepublish":"npm run build",
},
"homepage": "https://github.com/Nadav/My.JS.Infra#readme",
"devDependencies": {
...
"typescript": "^2.4.2",
...
},
"dependencies": {
...
"needle": "^1.4.2",
...
},
"files": [
"tsOutputs/**/*.js",
"tsOutputs/**/*.d.ts",
"tsOutputs/index.d.ts"
],
"types":"tsOutputs/index.d.ts",
"main":"tsOutputs/index.js"
}
All done. Now you can publish your common code.
npm install my-js-infra --save
Here's my tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "es6"],
"module": "umd",
"sourceMap": true,
"watch": false,
"outDir": "./tsOutputs",
"moduleResolution":"node" /* This must be specified in order for typescript to find the my-js-infra. Another option is to use "paths" and "baseUrl". Something like:
...
"baseUrl": ".", // This must be specified if "paths" is used.
"paths":{
"my-js-infra":["node_modules/my-js-infra/tsOutputs/index.d.ts"]
}
...
*/
}
}
You can read more on module resolution in Typescript in here: https://www.typescriptlang.org/docs/handbook/module-resolution.html
import {MyJsInfra } from "my-js-infra";
public doMagic(cmd, callback) {
try {
var request:MyJsInfra.Entities.HttpRequest = {
verb: "GET",
url: "http://www.google.com",
};
var client = new MyJsInfra.HttpClient();
client.doRequest(request, (err, data)=>{
if (err)
return callback(err, null)
return callback(null, data);
})
} catch (err) {
callback(err);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.