Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOCS] Add .js.flow documentation #8029

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions website/_data/guides.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@
- path: "/docs/libdefs/"
# - path: "/docs/libdefs/usage/"
- path: "/docs/libdefs/creation/"
additional_reading:
- guide: declarations

- id: declarations
pages:
- path: "/docs/declarations/"
additional_reading:
- guide: libdefs

# - id: errors
# pages:
Expand Down
7 changes: 7 additions & 0 deletions website/_data/i18n/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ docs_additional_reading: "Additional Reading"
"/docs/libdefs/usage/":
title: "Using Library Definitions"
description: ""
"/docs/declarations/":
title: "Declaration Files"
description: ".js.flow"
"/docs/modules/":
title: "Modules"
description: ""
Expand Down Expand Up @@ -426,6 +429,10 @@ guides:
description: >
Learn how to create and use library definitions for the third-party code
your code depends on.
declarations:
title: "Declaration Files"
description: >
Learn how to write and publish types alongside your NPM package.
# errors:
# title: "Debugging Errors"
# description: >
Expand Down
87 changes: 87 additions & 0 deletions website/en/docs/declarations/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
layout: guide
---

## What's a "Declaration File"? <a class="toc" id="toc-what-s-a-declaration-file" href="#toc-what-s-a-declaration-file"></a>

Let's look at a more general, and sometimes more convenient, way to
declare types for modules: `.js.flow` files.

The exported types of a module may be declared in a _declaration file_ with
the `.js.flow` extension, colocated with the corresponding _implementation
file_ with the `.js` extension.

A declaration file for a module shadows a
colocated implementation file for that module when typechecking other code
that may depend on that module.


For example, suppose we have the following code in a file `src/LookBeforeYouLeap.js`:

```js
// @flow
import { isLeapYear } from "./Misc";
if (isLeapYear("2020")) console.log("Yay!");
```

Next, suppose that `src/Misc.js` had an incompatible implementation of
`isLeapYear`, just as above.

```js
// @flow
export function isLeapYear(year: number): boolean {
return year % 4 == 0; // yeah, this is approximate
}
```

If we now create a declaration file `src/Misc.js.flow`, the declarations in it
will be used instead of the code in `src/Misc.js`. Let's say we have the
following declarations in `src/Misc.js.flow`.

> NOTE: The syntax for declarations in a declaration file is the same as we've seen in
> [Creating Library Definitions section](../libdefs/creation).

```js
// @flow
declare export function isLeapYear(year: string): boolean;
```

What do you think will happen?

Right, the `isLeapYear` call in `src/LookBeforeYouLeap.js` will typecheck.
As this example shows, declaration files must be written with care: it is up
to the programmer to ensure they are correct, otherwise they may hide type
errors.
That said, declaration files provide a very convenient way to write
specifications for modular typechecking. Sometimes, the implementation code
may not yet be free of type errors, but we may want to move on and come back
to fixing the type errors later. Another important use of this feature is for
libraries, whose implementation code may be too complex to typecheck
satisfactorily, but whose clients we still want to typecheck against
well-defined specifications.

## Inlining declarations in regular code <a class="toc" id="toc-inlining-declarations-in-regular-code" href="#toc-inlining-declarations-in-regular-code"></a>

As noted above, declarations should be distinct from regular code. But
sometimes, it is useful to do declarations "inline," as part of the source of
an implementation file.

**Proceed with caution!**

The most common use is writing "work-in-progress" code while ensuring that
your code typechecks. In the following example, say you want to finish writing
the function `fooList` without bothering to mock up its dependencies first: a
function `foo` that takes a `number`, and returns a `string` and a class
`List` that has a `map` method. Easy! (Just don't forget to replace the
declarations with proper implementations.)

```js
declare class List<T> {
map<U>(f: (x: T) => U): List<U>;
}
declare function foo(n: number): string;

function fooList(ns: List<number>): List<string> {
return ns.map(foo);
}
```
3 changes: 1 addition & 2 deletions website/en/docs/libdefs/creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ declare module "some-third-party-library" {
The name specified in quotes after `declare module` can be any string, but it
should correspond to the same string you'd use to `require` or `import` the
third-party module into your project. For defining modules that are accessed via
a relative `require`/`import` path, please see the docs on the `.js.flow` files
which will be available soon.
a relative `require`/`import` path, please see the docs on the [`.js.flow` files](../declarations)

Within the body of a `declare module` block, you can specify the set of exports
for that module. However, before we start talking about exports we have to talk
Expand Down