How to write typings
When you write typed definitions for DefinitelyTyped, you create a pull request on DefinitelyTyped with the corresponding .d.ts
file and you are done. In the .d.ts
file you write either an ambient internal module
or ambient external module
as in the handbook.
Things are a little bit different when you write a definition with Typings.
While it is definitely not harder than writing typed definitions for DefinitelyTyped, there isn't a clear term of reference on how to write a definition with Typings.
First things first...terminology
Going through the handbook and spec to understand everything you need to write typings is a great thing to do, but it isn't fun. Also, since TypeScript is rapidly improving, some information in the handbook is out of date.
Here are a list of terms that are relevant in writing typings so you can cut the chase.
If you like to learn by example, you can skim through this section and read the next one. Things will become more clear as you move along.
Typescript terminologies
ambient (declaration)
http://www.typescriptlang.org/Handbook#modules-working-with-other-javascript-libraries
We call declarations that don't define an implementation "ambient". Typically these are defined in .d.ts files. If you're familiar with C/C++, you can think of these as .h files or 'extern'.
- Declaration that don't define an implementation
- all
.d.ts
files
- I think it is named so to describe "These files describe the target JS in ambient to the TS world"
ambient modules
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md
- modules === external modules
- i.e. ambient modules === ambient external module
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#ambient-modules
We could define each module in its own .d.ts file with top-level export declarations, but it's more convenient to write them as one larger .d.ts file. To do so, we use a construct similar to ambient namespaces, but we use the module keyword and the quoted name of the module which will be available to a later import.
- Refers to both top-level export declaration and
declare module "name" {
.
ambient namespaces
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#introduction
- namespaces === internal modules
- i.e. ambient namespaces === ambient internal module
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#ambient-namespaces
declare namespace D3
+ declare var d3: D3.Base
to declare global object.
declare var d3
is needed because in the example D3
is a non-instantiated namespace.
external module
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md
- external modules are now modules
export =
and import = require()
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#export--and-import--require
- When importing a module using
export =
, TypeScript-specific import X = require("module")
must be used to import the module.
https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-default-import-interop-with-systemjs
- In TypeScript 1.8, you can
import X from 'module';
or import * as X from 'module';
. The exact behavior depends on module: system|commonjs
and allowSyntheticDefaultImports: true|false
.
internal module
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#introduction
- internal modules are now namespaces
module
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#111-modules
- ES2015 module
- module === external module
- Contain top-level export and import directives
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#16-classes
- Not module pattern. module pattern === namespace === internal module
module keyword
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces%20and%20Modules.md
module X {
is equivalent to the now-preferred namespace X {
- When you write
declare module X {
, you are actually writing declare namespace X {
.
- i.e. you are writing namespace === internal module
microsoft/TypeScript#6808
- The
module
keyword will be gradually deprecated.
module pattern
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#110-namespaces
- JavaScript module pattern: encapsulate private fields and methods using closure variables
namespace
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#namespacing
Instead of putting lots of different names into the global namespace, let's wrap up our objects into a namespace.
- Top-level namespace will be global (if the file is not a
top-level declaration
, see below)
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#10-namespaces
- Formalization of the IIFE pattern
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#110-namespaces
- Namespace is module pattern
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#101-namespace-declarations
Namespaces are either instantiated or non-instantiated. A non-instantiated namespace is a namespace containing only interface types, type aliases, and other non-instantiated namespace. An instantiated namespace is a namespace that doesn't meet this definition. In intuitive terms, an instantiated namespace is one for which a namespace instance is created, whereas a non-instantiated namespace is one for which no code is generated.
- No code is generated for non-instantiated namespace
- i.e. it can only be used as type
- A namespace instance is created for instantiated namespace
- i.e. at top-level, it creates a global namespace object
top-level declaration
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#23-declarations (need to scroll down a bit)
- Top-level declarations in a source file with no top-level import or export declarations belong to the global namespace
- This applies to both module and namespace
- i.e.
declare namespace X {
creates a global namespace X
.
- Top-level declarations in a source file with one or more top-level import or export declarations belong to the module represented by that source file.
- i.e.
declare namespace X {
in such file does not create global namespace X
.
References