Skip to content

add typescript definitions and replace jsdoc with typedoc - #403

Merged
rochdev merged 9 commits into
v0.9.0from
typescript
Feb 21, 2019
Merged

add typescript definitions and replace jsdoc with typedoc#403
rochdev merged 9 commits into
v0.9.0from
typescript

Conversation

@rochdev

@rochdev rochdev commented Jan 2, 2019

Copy link
Copy Markdown
Member

This PR adds TypeScript definition files to officially support TypeScript out of the box instead of having to rely on @types/dd-trace. It also has the side effect to improve even JavaScript code completions in some IDEs such as Visual Studio Code. Now that we have typings, I've also replaced the current API documentation with an improved version based on typedoc.

To view a preview of the final docs, run:

yarn install
yarn typedoc

and then open ./out/index.html in a browser.

@rochdev rochdev added the docs label Jan 2, 2019
@brettlangdon

Copy link
Copy Markdown
Member

Should we just have typedoc be a devDependency of the main package.json?

Or maybe add a script to the docs/package.json for running typedoc?

Right now if I clone and run yarn typedoc I get an error since typedoc is not available to yarn via the main package.json.

I can't figure out if that sentence makes sense.

@rochdev

rochdev commented Jan 10, 2019

Copy link
Copy Markdown
Member Author

Should we just have typedoc be a devDependency of the main package.json?

The idea is to keep the dependency out so that we can better parallelize the build without unnecessary dependencies being pulled.

Right now if I clone and run yarn typedoc I get an error since typedoc is not available to yarn via the main package.json.

That is a bug that I'll submit a new commit for.

@perryh

perryh commented Jan 14, 2019

Copy link
Copy Markdown
Contributor

hi @rochdev,

I'm new to typescript. In index.d.ts, why aren't any of the type definitions exported? In my code, for example, I would like to specify that a variable is of type SpanOptions, but cannot because I don't have access to that interface.

Thanks!

@rochdev

rochdev commented Jan 14, 2019

Copy link
Copy Markdown
Member Author

@perryh This is something I need to fix in the PR before we can merge it. In the meantime, I would recommend to take a look at @types/dd-trace.

@alloy alloy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! ✨

Comment thread index.d.ts Outdated
* Please see the available [options](../interfaces/amqp10.options.html) to
* configure this plugin.
*/
declare namespace amqp10 {

@alloy alloy Jan 30, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is recommended (in the TS/DefinitelyTyped realm) to not use namespace. Moreover, the TS support in Babel 7 does not support it at all. When people really want namespaces, it's usually solved by utilizing multiple modules.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not sure which one should be used, but decided to go with namespace as it seems to be the construct recommended for "internal modules" according to the docs.

Do you have any good reference on the difference between the two and when one should be used instead of the other?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's hard to find a clear doc that states you should favour modules over namespaces and I'm sure there are still valid reasons to use namespaces. I personally follow the rule because it's what the DT repo uses through TSLint's recommended settings (which includes https://palantir.github.io/tslint/rules/no-namespace/).

When it comes to truly modelling a module, using module (or separate files to reflect modules) is a direct representation of reality. i.e. I could, if I wanted to, import one of the plugin modules. If I wanted TS to know about types of that module, using namespaces wouldn't make that happen. If you don't really want people to import modules, which seems to be the case here (?), then there's also no real point in modelling modules somewhat. Instead I'd just define an interface for each plugin that models the plugin config object you can pass to init, like we did in the DT types for this lib.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps interesting, yet still implicit, is this from the docs:

Starting with ECMAScript 2015, modules are native part of the language, and should be supported by all compliant engine implementations. Thus, for new projects modules would be the recommended code organization mechanism.

TS always wants to follow the standard but sometimes experiments with future possible additions to the spec. From reading this snippet and various 3rd party recounts it seems like this is what happened with namespaces and they are no longer encouraged.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @DanielRosenwasser do you have any input / know of a definitive document on this topic?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the Babel part is my main concern too. However, I’m now realizing that as long as you don’t write the libs source in TS it shouldn’t really matter. Babel doesn’t do any type-checking, for that you’re supposed to use tsc, so in this case the d.ts file would simply be ignored and it should all be fine.

As for the example of exporting eg constants from the plugin modules, in that scenario I would actually be more inclined to use modules over namespaces, because it means users will be able to import those exports from the modules directly, instead of only through the main module of the package.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. So basically for an import such as import "dd-trace/plugins/express" for example, it would work if there is a file named express.d.ts? I assumed this was only possible for actual .ts files only.

As a side note, I usually prefer to export everything from the main module to avoid the API being bound to the file structure, but I'm open to export the files directly if it's deemed useful.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, or you could use the declare module “some/path” { } declaration in your index.d.ts file.

You can ofc still also export them from the main module, but I like letting the decision up to the user as more than once have I had an exotic reason to only import a subset of a package.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the original code uses a namespace pattern for organization, namespaces are fine. New code probably shouldn't be authored using namespaces, but namespace is probably fine in .d.ts files.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will keep namespace for now and will update later if it causes any issues.

@rochdev

rochdev commented Jan 30, 2019

Copy link
Copy Markdown
Member Author

@alloy Thanks for looking into this PR! I'm by no means a TypeScript expert so any help is appreciated!

@alloy

alloy commented Feb 1, 2019

Copy link
Copy Markdown
Contributor

Sure thing!

One thing that comes to mind is that, because you don't actually use TS, your type defs aren't being exercised, so it might be a good idea to add a ‘test’ like we have in the DT version: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/dd-trace/dd-trace-tests.ts

@perryh

perryh commented Feb 2, 2019

Copy link
Copy Markdown
Contributor

@alloy hi :) should the type declarations from @types/dd-trace be exported? I'm having trouble referencing the types in my code.

only the trace variable is is exported: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/dd-trace/index.d.ts
another library in my project that I can reference types from w/o issue: https://github.com/brightcove/hot-shots/blob/master/types.d.ts
thanks!

@rochdev

rochdev commented Feb 2, 2019

Copy link
Copy Markdown
Member Author

One thing that comes to mind is that, because you don't actually use TS, your type defs aren't being exercised, so it might be a good idea to add a ‘test’ like we have in the DT version

@alloy I'll definitely add tests. So far I've been testing the types manually, but of course this doesn't scale at all.

@alloy

alloy commented Feb 2, 2019

Copy link
Copy Markdown
Contributor

@perryh Correct, currently really only the trace instance is exported. There’s this PR that exports more, but it needs some revision first DefinitelyTyped/DefinitelyTyped#32606

@rochdev

rochdev commented Feb 20, 2019

Copy link
Copy Markdown
Member Author

I would like to specify that a variable is of type SpanOptions, but cannot because I don't have access to that interface.

@perryh In general simply creating an object of any type (including literal) with the correct properties should just work. Are you having any specific issue?

@rochdev
rochdev changed the base branch from master to v0.9.0 February 20, 2019 21:39
@perryh

perryh commented Feb 20, 2019

Copy link
Copy Markdown
Contributor

I would like to specify that a variable is of type SpanOptions, but cannot because I don't have access to that interface.

@perryh In general simply creating an object of any type (including literal) with the correct properties should just work. Are you having any specific issue?

Without exports, I'm not able to use them in declarations. For example, I have to declare this variable as any instead of Scope:

// tslint:disable-next-line:no-any
  const scope: any = tracer.scopeManager().active();

Thanks!

Comment thread .circleci/config.yml

@brettlangdon brettlangdon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

> node --version
v10.15.0
> yarn type:test
yarn run v1.13.0
$ cd docs && yarn test
$ tsc --noEmit test
test.ts:119:17 - error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.

119 const promise = Promise.resolve();
                    ~~~~~~~

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Comment thread .circleci/config.yml
Comment thread docs/API.md
Comment thread docs/index.d.ts
* Tracer is the entry-point of the Datadog tracing implementation.
*/
export declare interface Tracer extends opentracing.Tracer {
startSpan(name: string, options?: SpanOptions): Span;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add documentation to these methods?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually a bug in typedoc where it should use the documentation from the parent. I'll try to add our own doc for now and figure out why this is happening later.

@rochdev
rochdev merged commit 33095a5 into v0.9.0 Feb 21, 2019
@rochdev
rochdev deleted the typescript branch February 21, 2019 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants