Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
48ac7f9
Intiial commit of @RyanCavanaugh's documentation
mhegazy Jul 4, 2016
a1323a7
Fix lint issues and remove unused files
mhegazy Jul 4, 2016
cf3cad9
Add links
mhegazy Jul 4, 2016
f83215b
Remove unused files
mhegazy Jul 4, 2016
80a7d6e
Remove old writing declaration files page
mhegazy Jul 4, 2016
3c75abc
Remove redundant headers
mhegazy Jul 4, 2016
8ca3497
Fix links
mhegazy Jul 4, 2016
04f99c3
Add publishing section
mhegazy Jul 4, 2016
83353e2
fix typos
mhegazy Jul 4, 2016
84b218f
Add a consumption section
mhegazy Jul 4, 2016
16ea13b
Update title
mhegazy Jul 4, 2016
b235810
Add redirect notice
mhegazy Jul 4, 2016
a7dc1b4
Fix lint issues
mhegazy Jul 5, 2016
53c0b4e
Remove extra paren
mhegazy Jul 5, 2016
0751425
Update links
mhegazy Jul 5, 2016
8242822
hide todo comments
mhegazy Jul 5, 2016
9bad0a6
Add redirect
mhegazy Jul 5, 2016
d0e9948
Fix links
mhegazy Jul 5, 2016
4170c48
Update By Example.md
DanielRosenwasser Jul 5, 2016
3089703
Update Consumption.md
DanielRosenwasser Jul 5, 2016
842c566
Update Introduction.md
DanielRosenwasser Jul 5, 2016
adc00a2
Remove folder link
mhegazy Jul 5, 2016
646e50b
Update Library Structures.md
DanielRosenwasser Jul 6, 2016
2791139
Fix example
mhegazy Jul 6, 2016
e5c99b7
Fix lint issues
mhegazy Jul 6, 2016
b296e18
Update Publishing.md
DanielRosenwasser Jul 6, 2016
23b7612
Fix grammer
mhegazy Jul 6, 2016
e66a0d5
Fix grammer
mhegazy Jul 6, 2016
1ce42d1
Merge pull request #336 from Microsoft/updateDtsPublishing
DanielRosenwasser Jul 7, 2016
158a533
Update Publishing.md
DanielRosenwasser Jul 7, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 1 addition & 28 deletions pages/Typings for NPM Packages.md
Original file line number Diff line number Diff line change
@@ -1,28 +1 @@
The TypeScript compiler resolves Node module names by following the [Node.js module resolution algorithm](https://nodejs.org/api/modules.html#modules_all_together).
TypeScript can also load typings that are bundled with npm packages.
The compiler will try to discover typings for module `"foo"` using the following set of rules:

1. Try to load the `package.json` file located in the appropriate package folder (`node_modules/foo/`). If present,read the path to the typings file described in the `"typings"` field. For example, in the following `package.json`, the compiler will resolve the typings at `node_modules/foo/lib/foo.d.ts`

```json
{
"name": "foo",
"author": "Vandelay Industries",
"version": "1.0.0",
"main": "./lib/foo.js",
"typings": "./lib/foo.d.ts"
}
```

2. Try to load a file named `index.d.ts` located in the package folder (`node_modules/foo/`) - this file should contain typings for the package.

The precise algorithm for module resolution can be found [here](https://github.com/Microsoft/TypeScript/issues/2338).

### Your definition files should

* be`.d.ts` files
* be written as external modules
* not contain triple-slash references

The rationale is that typings should not bring new compilable items to the set of compiled files; otherwise actual implementation files in the package can be overwritten during compilation.
Additionally, **loading typings should not pollute global scope** by bringing potentially conflicting entries from different version of the same library.
> ## This page has been moved to [Publishing](./declaration files/Publishing.md)
269 changes: 1 addition & 268 deletions pages/Writing Declaration Files.md
Original file line number Diff line number Diff line change
@@ -1,268 +1 @@
# Introduction

When using an external JavaScript library, or new host API, you'll need to use a declaration file (.d.ts) to describe the shape of that library.
This guide covers a few high-level concepts specific to writing declaration files, then proceeds with a number of examples that show how to transcribe various concepts to their matching declaration file descriptions.

# Guidelines and Specifics

## Workflow

The best way to write a .d.ts file is to start from the documentation of the library, not the code.
Working from the documentation ensures the surface you present isn't muddied with implementation details, and is typically much easier to read than JS code.
The examples below will be written as if you were reading documentation that presented example calling code.

## Namespacing

When defining interfaces (for example, "options" objects), you have a choice about whether to put these types inside a namespace or not.
This is largely a judgement call -- if the consumer is likely to often declare variables or parameters of that type, and the type can be named without risk of colliding with other types, prefer placing it in the global namespace.
If the type is not likely to be referenced directly, or can't be named with a reasonably unique name, do use a namespace to prevent it from colliding with other types.

## Callbacks

Many JavaScript libraries take a function as a parameter, then invoke that function later with a known set of arguments.
When writing the function signatures for these types, *do not* mark those parameters as optional.
The right way to think of this is *"What parameters will be provided?"*, not *"What parameters will be consumed?"*.
While TypeScript 0.9.7 and above does not enforce that the optionality, bivariance on argument optionality might be enforced by an external linter.

## Extensibility and Declaration Merging

When writing declaration files, it's important to remember TypeScript's rules for extending existing objects.
You might have a choice of declaring a variable using an anonymous type or an interface type:

#### Anonymously-typed var

```ts
declare var MyPoint: { x: number; y: number; };
```

#### Interfaced-typed var

```ts
interface SomePoint { x: number; y: number; }
declare var MyPoint: SomePoint;
```

From a consumption side these declarations are identical, but the type `SomePoint` can be extended through interface merging:

```ts
interface SomePoint { z: number; }
MyPoint.z = 4; // OK
```

Whether or not you want your declarations to be extensible in this way is a bit of a judgement call.
As always, try to represent the intent of the library here.

## Class Decomposition

Classes in TypeScript create two separate types: the instance type, which defines what members an instance of a class has, and the constructor function type, which defines what members the class constructor function has.
The constructor function type is also known as the "static side" type because it includes static members of the class.

While you can reference the static side of a class using the `typeof` keyword, it is sometimes useful or necessary when writing declaration files to use the *decomposed class* pattern which explicitly separates the instance and static types of class.

As an example, the following two declarations are nearly equivalent from a consumption perspective:

#### Standard

```ts
class A {
static st: string;
inst: number;
constructor(m: any) {}
}
```

#### Decomposed

```ts
interface A_Static {
new(m: any): A_Instance;
st: string;
}
interface A_Instance {
inst: number;
}
declare var A: A_Static;
```

The trade-offs here are as follows:

* Standard classes can be inherited from using `extends`; decomposed classes cannot. This might change in later version of TypeScript if arbitrary `extends` expressions are allowed.
* It is possible to add members later (through declaration merging) to the static side of both standard and decomposed classes
* It is possible to add instance members to decomposed classes, but not standard classes
* You'll need to come up with sensible names for more types when writing a decomposed class

## Naming Conventions

In general, you shouldn't prefix interfaces with `I` (e.g. `IColor`).
Because the concept of an interface in TypeScript is much more broad than in C# or Java, the `IFoo` naming convention is not broadly useful.

# Examples

Let's jump in to the examples section. For each example, sample *usage* of the library is provided, followed by the declaration code that accurately types the usage.
When there are multiple good representations, more than one declaration sample might be listed.

## Options Objects

#### Usage

```ts
animalFactory.create("dog");
animalFactory.create("giraffe", { name: "ronald" });
animalFactory.create("panda", { name: "bob", height: 400 });
// Invalid: name must be provided if options is given
animalFactory.create("cat", { height: 32 });
```

#### Typing

```ts
namespace animalFactory {
interface AnimalOptions {
name: string;
height?: number;
weight?: number;
}
function create(name: string, animalOptions?: AnimalOptions): Animal;
}
```

## Functions with Properties

#### Usage

```ts
zooKeeper.workSchedule = "morning";
zooKeeper(giraffeCage);
```

#### Typing

```ts
// Note: Function must precede namespace
function zooKeeper(cage: AnimalCage);
namespace zooKeeper {
var workSchedule: string;
}
```

## New + callable methods

#### Usage

```ts
var w = widget(32, 16);
var y = new widget("sprocket");
// w and y are both widgets
w.sprock();
y.sprock();
```

#### Typing

```ts
interface Widget {
sprock(): void;
}

interface WidgetFactory {
new(name: string): Widget;
(width: number, height: number): Widget;
}

declare var widget: WidgetFactory;
```

## Global / External-agnostic Libraries

These libraries can be used as either globals or imports.
In a module file (one with any imports/exports), using these as globals is not allowed.
These are also known as [UMD](https://github.com/umdjs/umd) modules.

#### Usage

```ts
// Either
import x = require("zoo");
x.open();
// or
zoo.open();
```

#### Typing

```ts
export function open(): void;
export as namespace zoo;
```

## Single Complex Object in Modules

#### Usage

```ts
// Super-chainable library for eagles
import Eagle = require("./eagle");

// Call directly
Eagle("bald").fly();

// Invoke with new
var eddie = new Eagle("Mille");

// Set properties
eddie.kind = "golden";
```

#### Typing

```ts
interface Eagle {
(kind: string): Eagle;
new (kind: string): Eagle;

kind: string;
fly(): void
}

declare var Eagle: Eagle;

export = Eagle;
```

## Function as an Module

This is a common pattern for modules whose imported entities are callable functions.

#### Usage

```ts
import sayHello = require("say-hello");
sayHello("Travis");
```

#### Typing

```ts
declare module "say-hello" {
function sayHello(name: string): void;
export = sayHello;
}
```

## Callbacks

#### Usage

```ts
addLater(3, 4, x => console.log("x = " + x));
```

#### Typing

```ts
// Note: 'void' return type is preferred here
function addLater(x: number, y: number, callback: (sum: number) => void): void;
```

Please post a comment [here](https://github.com/Microsoft/TypeScript-Handbook/issues) if there's a pattern you'd like to see documented!
We'll add to this as we can.
> ## This page has been moved to [Publishing](./declaration files/Introduction.md)

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.

There needs to be some sort of redirect here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done.

Loading