Typescript: How can I let JSDoc reference to type in another module

Created on 21 Apr 2016  路  18Comments  路  Source: microsoft/TypeScript

I have some d.ts files in my project and any files without module could be reference any class inside it directly. But some files is declare module and cannot be referred to it

This module also contain - sign in its name (it is aws-sdk from aws-sdk.d.ts)

Question

Most helpful comment

Is there any support to pull in a type defined in a jsdoc from another file yet ?
file1.js
/** @typedef {Object} TypeA */

I want to use that type in another file file2.js how can I do that in typescript ?

All 18 comments

Just found that reference module just work fine. It just cannot reference module name with - sign in its name and awssdk module using declare module "aws-sdk"

Was JSDoc support reference module by ID?

I am having hard time piecing together the repro. Can you provide a self-contained sample we can look at?

@mhegazy

I use tsd to pull aws-sdk.d.ts into typings folder

And then as you can see. the code in aws-sdk.d.ts is declare module "aws-sdk" { }

The module name is aws-sdk which is not possible to use at @type or @param for jsdoc

What I want is something like

/** @params {aws-sdk.DynamoDB} dynamo */
function DoWork(dynamo) {
    // dynamo will reference to DynamoDB class defined in aws-sdk.d.ts and can get intellisense
}

Current workaround I use is rename it in aws-sdk.d.ts as declare module awssdk { } but it not consistence with the original tsd

the module name shoudl not be used as an identifier. it works for some package, e.g. react, as they define a global variable React that has the same shape as the module. aws-sdk does not have that, so you need to import it.

import * as AWS from "aws-sdk";


/** @param {AWS.DynamoDB} dynamo */
function DoWork(dynamo) {

}

@mhegazy That's work. But I still need to use it on node server under ES5 (AWS Lambda latest node version is nodejs 4) it cause error with reserved keyword import

So I try to find a way to have it work with only jsdoc comment

Also I have seen there are syntax like this

declare module A {
    export = a;
}

So I made my own ts file and write

import * as sdk from "aws-sdk"
declare module AWSSDK {
    export = sdk;
}

but it still didn't work

So aws-sdk can be used without being imported? if so this is an error in the declaration file, and should be reported on definitely typed.

For workarounds, neither or these would work. you want to use the new UMD module definition, (added in TS 2.0) https://github.com/Microsoft/TypeScript/issues/7125:

/// file: my-aws-sdk.d.ts
export * from "aws-sdk"
export as namespace AWS;
/// file: app.js

/// <reference path="my-aws-sdk.d.ts" />

/** @param {AWS.DynamoDB} dynamo */
function DoWork(dynamo) {

}

@mhegazy No it's not. I mean I already try using import and it make intellisense work. But it cannot use in my target server so I can't use your solution

That's that. so I need to wait for TS 2.0

Thank you very much for your help

@mhegazy Also I would like to suggest that, in addition to yours export as namespace syntax. There should be something like /** @import a as b */ for pure JSDoc style too

Is there any support to pull in a type defined in a jsdoc from another file yet ?
file1.js
/** @typedef {Object} TypeA */

I want to use that type in another file file2.js how can I do that in typescript ?

Like @tjtaill, I also want to be able to import @typedef definitions from other modules. Do we need to create a second issue to track @tjtaill鈥檚 request, or is that covered by #14377?

I am trying to do something similar, I am using a jsconfig.json file and trying to set up a Karma configuration.

karma.conf.js

/// <reference types="karma" />

/**
 * @param {Config} [config]
 */
function setConfig(config) {
    config.set({
        // configuration...
    });
}

VSCode just says [js] Cannot find name 'Config'. I have tried @param {karma.Config} as well but no joy. I am either doing something wrong or this behaviour isn't supported yet.

^ I tried above with no luck.

How would you reference something like firebase-admin type definition?

https://unpkg.com/[email protected]/lib/index.d.ts

It includes those definitions:

// firebase-admin type definition
import {Bucket} from '@google-cloud/storage';
import * as _firestore from '@google-cloud/firestore';

declare namespace admin {
  interface AppOptions {
    credential?: admin.credential.Credential;
    databaseAuthVariableOverride?: Object;
    databaseURL?: string;
    storageBucket?: string;
  }

  function app(name?: string): admin.app.App;
}

declare namespace admin.app {
  interface App {
    name: string;
    options: admin.AppOptions;
  }
}

declare namespace admin.firestore {
  export import FieldPath = _firestore.FieldPath;
}

declare module 'firebase-admin' {
}

export = admin;

If i try to bridge with:

// lib/admin.d.ts
export * from 'firebase-admin';
export as namespace admin;

If I reference lib/admin.d.ts, and then type to use admin.app.App, tsc complains with "error TS2694: Namespace '"lib/admin"' has no exported member 'app'".

// lib/index.js
// @ts-check
/// <reference path="./admin.d.ts" />

'use strict';

const admin = require('firebase-admin');

/**
 * @type {admin.app.App|null}
 */
let defaultApp = null;

for some people trying to use TS typings in plain JS, using JSDoc, sometimes I need to double export for it to work, like so:

import * as winston from 'winston'
export = winston
export as namespace winston

if you don't use export = winston, everything becomes any. if you omit the export as namespace, you get Cannot find namespace 'winston'. so a code like this can now work:

/// <reference path="my-winston.d.ts" />
/**
 * @type {winston.LoggerInstance | null}
 */
var logger = null

Based on @mhegazy answer, but with plain requires and avoiding dash in aws-sdk namespace.

image

const AWS = require('aws-sdk');

/**
 * @param {AWS.DynamoDB} dynamo 
 */
module.exports = function(dynamo){
    return handler;

    function handler(event, context, callback){
        let msg = `We are running ${event.name}`;
        console.log(msg)
        callback(null, { msg });

    }    
}

An ES6 import of types or a reference do not import anything at run time however.

Even with that example where the caller would have to import that package anyway, a test might want to avoid any side effect of the import.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kyasbal-1994 picture kyasbal-1994  路  3Comments

wmaurer picture wmaurer  路  3Comments

Zlatkovsky picture Zlatkovsky  路  3Comments

Antony-Jones picture Antony-Jones  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments