2

I just published a npm package written in typescript. Currently I have a lot of trouble getting the definition recognized by typescript (webback and vscode). The only solution that worked so far was to create a folder with the definition in node_modules/@types

Briefly this is my package setup:

tsconfig.json

{
    "compilerOptions": {
        ...
        "outDir": "./lib/",
        "declaration": true,
        "declarationDir": "./src/",
    }
}

package.json

{
    ...
    "types": "./index.d.ts",
}

index.d.ts

/// <reference path="src/nano-data-binding.d.ts" />

src/nano-data-binding.d.ts

I keep it in /src because it's autogenerated and I cannot control the path of the import. Also if I try to use only declare var ... without import export statements to get a script instead of a module.

import { StringOrHTMLElement } from './interfaces/nano-data-binding';
export declare function nanoBind(parent: HTMLElement, ...selectors: StringOrHTMLElement[]): HTMLElement[];
export declare function nanoBindAll(parent: HTMLElement, ...selectors: string[]): HTMLElement[];

Feel free to install the package, maybe it is just a small mistake somewhere. Basically I want to get the nanoBind() and nanoBindAll() declared as globals.

Edit

Additional things I tried. Nothing works.

package.json - Npm package

{
    ...
    "types": "lib/nano-data-binding.d.ts",
    "typings": "lib/nano-data-binding.d.ts",
    "typescript": {
        "definition": "lib/nano-data-binding.d.ts"
    },
}

tsconfig.json - Local project

{
    ...
    "files": [
        "node_modules/nano-data-binding/lib/nano-data-binding.d.ts"
    ]
}
8
  • Have you distributed the typing files in your package? You also don't need the redirection (using index.d.ts and use /// <ref). Just point to the actual typing files from package.json directly. Commented Dec 27, 2017 at 1:54
  • BTW, /// <reference is for global script files, as a package, you would not use that syntax. Just import '...'. Commented Dec 27, 2017 at 1:55
  • I have tried all these suggestions before posting, I was pointing to the actual file. I also tried using typings. And various other things. It just refuses to register as a definition. The definition is definitely in the package. Commented Dec 27, 2017 at 8:55
  • I've been looking at other packages trying to figure out if I deed something wrong. Nothing stands out. Is there a way to confirm that an interface is loaded, other than just waiting for the error? Commented Dec 27, 2017 at 9:01
  • Can you show how the nano-data-binding.d.ts looks like? It should be automatic, you don't have to do anything except types/typings: ... in your package.json. See any of my packages for example. e.g. color-map Commented Dec 27, 2017 at 12:00

3 Answers 3

2

In your package.json you need to rename the types field to typings And yes, triple slash directive is not needed here

Sign up to request clarification or add additional context in comments.

2 Comments

I used the triple slash in order to be able to add more definitions, indeed it's not really needed. Before posting I tried pointing directly to the folder and to the root index.d.ts where the actual definition was located.
"types" and "typings" are synonymous typescriptlang.org/docs/handbook/declaration-files/…
1

Finally found something that works. It looks like it's enough to use index.d.ts in the root level or specify a custom route in package.json of the package.

The problem was with my definition. It needs to declare a module.

index.d.ts

type StringOrHTMLElement = string | HTMLElement
declare var nanoBind: (parent: HTMLElement, ...selectors: StringOrHTMLElement[]) => HTMLElement[];
declare var nanoBindAll: (parent: HTMLElement, ...selectors: string[]) => HTMLElement[];

declare module 'nano-data-binding' {
    export var nanoBind: (parent: HTMLElement, ...selectors: any[]) => HTMLElement[];
    export var nanoBindAll: (parent: HTMLElement, ...selectors: string[]) => HTMLElement[];
}

And than the way it is imported

main.ts

import * as ndb from 'nano-data-binding' // Imports script and definition
require('nano-data-binding') // Ignores definition

3 Comments

This is not the way. So I know what’s your problem. Will post an answer
This is a way of augmenting someone elses type defs.. I've posted an answer above.. types -> typings in package.json
I found globals.d.ts in the typescript documentation. Maybe I got it the wrong way. Says that namespace is for globals, which is my case.
1

The problem you have is due to your tsconfig.json tries to explicitly include the typing file. npm package typings file are loaded automatically when you specify either types or typings field in your package.json.

When you remove the entry in your files array in your tsconfig.json, it should just work.

The solution you found (adding declare module 'nano-data-binding' { }) is a solution for creating custom typings for some packages without typings.

To be a bit more technical, when a typings file (d.ts) does not contain top-level import export statement, it is an ambient script file and it is globally scoped. That's why you need declare module '...' to indicate which module your are adding typings for.

You typically use them as in How to consume the Moment.js TypeScript definition file if my site is already using moment.min.js?

1 Comment

The trouble is that I have removed the files option from tsconfig.json some time ago. A lot of the tests I made were running without this option. I will keep looking into it. I hope I will find the real trouble maker. Maybe I should try to import it in a clean project. Maybe something interferes. I will be doing some tests and report back on the results.Thank you for the answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.